Order of evaluation of a += a++;

deadalnix via Digitalmars-d digitalmars-d at puremagic.com
Mon Mar 30 17:49:30 PDT 2015


On Tuesday, 31 March 2015 at 00:38:25 UTC, Andrei Alexandrescu 
wrote:
> On 3/30/15 4:12 PM, deadalnix wrote:
>> On Monday, 30 March 2015 at 20:31:10 UTC, Temtaime wrote:
>>> I think DMD does it right. This is commented behavior.
>>
>> This is certainly not. SDC act as per spec. DMD act as per DMD.
>>
>> But maybe random evaluation order with incorrect documentation 
>> is what
>> we want.
>
> As an aside, we can change the reference to do what we think is 
> right. The principled way is to go by two rules:
>
> 1. Use left-to-right wherever there's a choice
>
> 2. Express complex operations in terms of lowerings.
>
> So now we have to figure e1 += e2. By rule (2) we should go 
> with this lowering:
>
> e1 += e2
>
> -\>
>
> (ref a, b) { a = cast(typeof(a)) (a + b); }(e1, e2)
>
> By rule (1) we should evaluate e1 before e2 when passing into 
> the lambda. To apply that to i += i++, recall this lowering:
>
> i++
>
> -\>
>
> (ref x) { auto y = x; ++x; return y; }(i)
>
> which takes as to this lowering:
>
> i = i++
>
> -\>
>
> (ref a, b) { a = cast(typeof(a)) (a + b); }( // lambda1
>   i,
>   (ref x) { auto y = x; ++x; return y; }(i) // lambda2
> )
>
> So first we evaluate the address of i (trivial). Then we 
> evaluate lambda2, which increments i before the += lambda1.
>
> So assuming i starts at 5, by the time lambda1 is called i is 6 
> and b has value 5. Then lambda1 executes, bringing i to 11.
>
> It seems that dmd is correct and we should fix the spec and sdc.
>
>
> Andrei

Why are you doing the replacement top/down rather than bottom up ?


More information about the Digitalmars-d mailing list