Struct assignment, possible DMD bug?

ixid nuaccount at gmail.com
Sat Sep 29 20:13:10 PDT 2012


On Sunday, 30 September 2012 at 00:24:34 UTC, Ali Çehreli wrote:
> On 09/29/2012 04:02 PM, Timon Gehr wrote:
> > 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?
>
> I am confused. Of course single mutation and many reads should 
> be fine.
>
> >
> >> 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.
>
> Yes. And in this case it is the compiler-generated constructor. 
> The OP's problem goes away if there is a user-provided 
> constructor:
>
>     struct S {
>         int a, b, c;
>
>         this(int a, int b, int c)
>         {
>             this.a = a;
>             this.b = b;
>             this.c = c;
>         }
>     }
>
> Now it is as expected:
>
>     assert(s == S(4,1,6));
>
> > 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
>
> Silly me! :p
>
> Ali

This would still seem to be a very poor behaviour worth fixing. 
What is the compiler generating instead of the constructor 
example you gave?


More information about the Digitalmars-d-learn mailing list