D and expression evaluation order.

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Thu Apr 26 15:46:37 PDT 2007


Bruno Medeiros wrote:
> Frits van Bommel wrote:
>> Bruno Medeiros wrote:
>>> As we know, in C/C++ there are a lot of cases where the order of
>>> evaluation of an expression is undefined.
>>>
>>>   i = i++;
>>>   c = a + (a = b);
>>>   func(++i, ++i);
>>>
>>> D goes one step further by defining that any such behavior is illegal:
>>> "Unless otherwise specified, the implementation is free to evaluate the
>>> components of an expression in any order. It is an error to depend on
>>> order of evaluation when it is not specified." in
>>> http://www.digitalmars.com/d/expression.html .
>>
>> Actually, if I read that right it just says that the order of 
>> evaluation is undefined and should not be relied upon. Just like C/C++.
> 
> Read the paragraph ahead in the doc. In D that is considered a 
> language(i.e. compile) error and so the compiler can issue an error. In 
> C/C++ it is merely undefined program behavior, the code remains compilable.

IIRC[1] the C++ standard includes "causes a compile error" as one of the 
possible consequences of undefined behavior. I'm not sure about C.


[1] I've been staying away from C++ since I started using D, so this is 
by no means a given...

[snip]
>> Unspecified evaluation order is an optimization opportunity.
>> For instance, the most efficient parameter evaluation order can be 
>> dependent on the calling convention, which is platform-dependent. For 
>> instance on x86 and amd64 platforms the most efficient evaluation 
>> order can very well be to evaluate right-to-left, since typical 
>> calling conventions specify the last argument is to be pushed onto the 
>> stack first[1]. (There are good reasons for that, mostly to do with 
>> varargs)
[snip]
> 
> In that case, it is possible for the compiler to detect if the 
> evaluation order matters, and if it doesn't (currently the only allowed 
> situation in D), it can push the arguments in any order it pleases him.

<nitpick> Actually, if you check the spec it says the compiler is 
allowed to issue an error if it detects the _result_ of the expression 
depends on evaluation order. It doesn't seem to mention side-effects at 
all, so evaluation order is technically allowed to matter (though it's 
still an error to _depend_ on it). Well, unless you count side-effects 
as part of the "result" of an expression... </nitpick>

> Even if that wasn't possible, I'm not sure that with modern CPU 
> technology, right-to-left calling conventions (last argument on top) 
> would be any slower to call with an left-to-right eval order, than with 
> an undefined order. Then again, I'm no Assembler or CPU optimization 
> expert, so correct if I'm wrong.

Nor am I, but I've inspected a lot of the assembly code generated for my 
programs and often the DMD and GDC optimizers apparently decided to 
evaluate (roughly) right-to-left...



More information about the Digitalmars-d mailing list