Why D const is annoying

Timon Gehr timon.gehr at gmx.ch
Mon Dec 12 06:46:54 PST 2011


On 12/12/2011 01:50 PM, Steven Schveighoffer wrote:
> On Sun, 11 Dec 2011 12:07:37 -0500, Mafi <mafi at example.org> wrote:
>
>> Am 10.12.2011 21:25, schrieb Walter Bright:
>>> On 12/10/2011 11:03 AM, Mehrdad wrote:
>>>> So how are you supposed to implement opApply on a container (or e.g.
>>>> here, a
>>>> matrix)? Copy/paste the code for const- and non-const versions?
>>>
>>> Internal to a function, inout behaves like 'const'. You won't be able to
>>> modify the data. Therefore, if there is no inout in the return type, use
>>> 'const' in the parameter list instead.
>>>
>>> The purpose of inout is to transmit the 'constness' of the function
>>> argument type to the return type, using only one implementation of that
>>> function. That requires the function to internally regard inout as
>>> const.
>>
>> But what about:
>> void f(ref inout(int)* a, inout(int)* b) { a = b; }
>> This cant work with const because that would violate the const system.
>> I think the rule should be that either the return type must be inout
>> or at least one ref/out parameter.
>> Am I overlooking something?
>
> That was brought up during discussion on adding the feature. One of the
> reasons inout is viable is because a) the source and result of where the
> constancy flows is well defined and b) the exit point is an rvalue
>
> Allowing ref parameters fails both those rules.
>
> Consider this:
>
> void bad(ref inout(int)* a, ref inout(int)* b);
>
> which is the entry and which is the exit? Is a set to b, or b set to a?
>
> Now, also consider that you can't affect the constancy of the result,
> because the type of the parameter is already defined. e.g.:
>
> // note that your example shouldn't even be valid, because you can't
> implicitly cast through two mutable references
> int a;
> auto pa = &a;
> immutable int b;
> auto pb = &b;
>
> f(a, b);
>
> How can this affect a? its type is already decided. Compare that to:
>
> inout(int)* g(inout(int)* b) { return b;}
>
> auto pa = g(pb);
>
> clean and simple.
>
> -Steve

This currently compiles:

inout(void) very_bad(ref inout(int)* a, ref inout(int)* b){a = b;}

void main(){
     immutable int a=2;
     int *x;
     immutable(int)* y=&a;
     very_bad(x,y);
     *x=1;
     assert(*y==a); // fail
}

How does the design catch this error? Will inout** = inout** assignments 
be disallowed?


More information about the Digitalmars-d mailing list