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