Order of evaluation - aka hidden undefined behaviours.

Don Clugston dac at nospam.com
Wed Sep 26 03:13:01 PDT 2012


On 26/09/12 01:31, H. S. Teoh wrote:
> 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.

I expected "BCA" too. Left associative expressions evaluated 
left-to-right, right associative expressions evaluated right-to-left.



More information about the Digitalmars-d mailing list