Best practices for logical const

Steven Schveighoffer schveiguy at yahoo.com
Sat Feb 15 21:22:33 PST 2014


On Sun, 16 Feb 2014 00:14:07 -0500, Meta <jared771 at gmail.com> wrote:

> On Sunday, 16 February 2014 at 04:46:34 UTC, Steven Schveighoffer wrote:
>> It is safe if you can guarantee the input is ultimately mutable. But  
>> there is no way to enforce such a guarantee. It is on the caller to  
>> make sure that is true.
>>
>> I don't see why inout should be identified as any different from const  
>> in this respect. You could just as easily say the same thing about  
>> const.
>>
>> -Steve
>
> Which is what I said in an earlier post. Wouldn't you be able to do this  
> with a template somehow?
>
> template LogicalConst(T)
> if (isMutable!T)
> {
>      alias LogicalConst = inout(T);
> }
>
> void bumpWithConstArg(T)(ref LogicalConst!T t)
> {
>      //Compiler error if you try to modify t
>      //t += 1;
>
>      //Fine, cast it to mutable then modify
>      //Nothing unsafe here because we verified t is mutable
>      cast(T)t += 1;
> }
>
> void main()
> {
>      immutable n = 0;
>      //No IFTI match because n is immutable
>      bumpWithConstArg(n);
>
>      auto m = 0;
>      //Okay, m is mutable
>      bumpWithConstArg(m);
> }
>
> This doesn't actually work, but this is just off the top of my head.

I think you are making a wrong turn somewhere. This has exactly the same  
behavior:

void bumpWithConstArg(T)(ref T t)
{
    t += 1;
}

void main()
{
    immutable n = 0;
    bumpWithConstArg(n); // fails to compile

    auto m = 0;
    bumpWithConstArg(n);
}

The problem you have to solve is this:

void foo(const(int) t)
{
    bumpWithConstArg(t);
}

void main()
{
    immutable n = 0;
    foo(n); // needs to fail

    auto m = 0;
    foo(m); // needs to work.
}

-Steve


More information about the Digitalmars-d mailing list