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 ?

Reply via email to