On 09/30/2012 12:51 AM, Ali Çehreli wrote:
On 09/29/2012 11:16 AM, Timon Gehr wrote:
> On 09/29/2012 06:26 PM, Maxim Fomin wrote:
>>> S s = S(1,2,3);
>>> s = S(4, s.a, 6);
>>>
>>> assert(a == [4,1,6]);
>>> assert(s == S(4,4,6));
>>> }
>>>
>>> Setting the struct writes s.a before evaluating it while the reverse
>>> is true of the array assignment. Using DMD 2.0.60. GDC does what I'd
>>> expect and gives both as 4,1,6.
>>
>> I think this is notorious "i = ++i + ++i".
>
> There is only one mutating sub-expression.
But that mutation is happening to an object that is also being read
inside the same expression.
This is one of the definitions of undefined behavior, not a compiler bug.
>> Statement s = S(4, s.a, 6) writes to s object and simultaneously reads
>> it.
>> http://dlang.org/expression.html states that assign expression is
>> evaluated in implementation defined-manner and it is an error to depend
>> on things like this.
>
> No evaluation order of the assignment expression can possibly lead to
> this result. This seems to be a DMD bug.
The compiler seems to be applying an optimization, which it is entitled
to as long as the language definition is not violated.
Technically there is no language definition to violate.
If we are using the same object both to read and write in the same
expression, then we should expect the consequences.
No. Why?
Disclaimer: I assume that D's rules are the same as C and C++ here.
C and C++ do not have struct literals and if I am not mistaken,
constructor invocation is a sequence point.
Besides, this does not make any sense, what is the relevant part of the
standard?
int c = 0;
c = c+1; // c is both read and written to in the same expression