Order of evaluation - aka hidden undefined behaviours.

Iain Buclaw ibuclaw at ubuntu.com
Tue Sep 25 15:58:57 PDT 2012


Pop quiz!

Analyse this code:
----
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?


Regards,
Iain.


More information about the Digitalmars-d mailing list