Order of evaluation of a += a++;

Andrei Alexandrescu via Digitalmars-d digitalmars-d at puremagic.com
Mon Mar 30 17:38:25 PDT 2015


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



More information about the Digitalmars-d mailing list