Order of evaluation - aka hidden undefined behaviours.

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Sep 25 16:31:26 PDT 2012


On Wed, Sep 26, 2012 at 01:10:00AM +0200, Timon Gehr wrote:
> On 09/26/2012 12:58 AM, Iain Buclaw wrote:
[...]
> >string abc;
> >
> >float[] A()
> >{
> >     abc ~= "A";
> >     return [];
> >}
> >
> >float[] B()
> >{
> >     abc ~= "B";
> >     return [];
> >}
> >
> >float[] C()
> >{
> >     abc ~= "C";
> >     return [];
> >}
> >
> >void main()
> >{
> >     A()[] = B()[] + C()[];
> >     assert(abc == "???");
> >}
> >----
> >
> >Without cheating, I invite people to have a good guess what 'abc' is
> >equal to, but just to narrow it down.
> >
> >1)  It isn't "ABC".
> >2)  On x86/x86_64, it isn't "ACB".
> >3)  On everything else, it's the reverse of what you'd expect on
> >x86/x86_64.
> >
> >The problem here is that the array operation A[] = B[] + C[] gets
> >transformed into an extern(C) call.  And because there's no strict rules
> >in place over the order of which it's parameters are evaluated, it could
> >go either way (LTR, or RTL).
> >
> >Serious note: This test is bogus as this and similar other failing tests
> >on non-x86 platforms are not at all obvious to the users who get issues.
> >So what are we to do about it?
[...]
> As far as my understanding of the issue goes, the correct answer is
> "ABC", and compilers that do not produce "ABC" are buggy.
> 
> The solution is to transform the code to code that evaluates the
> arguments to the extern(C) call in the correct order and eg. stores
> them in temporaries before passing them on.
[...]

Shouldn't it be BCA? I'd expect the assignment operation to take place
last, so the corresponding expression should be evaluated last.


T

-- 
Leather is waterproof.  Ever see a cow with an umbrella?


More information about the Digitalmars-d mailing list