D and expression evaluation order.

Bruno Medeiros brunodomedeiros+spam at com.gmail
Thu Apr 26 14:42:13 PDT 2007


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.

>> That's nice, but why not go all the way, and actually define an
>> evaluation order for such expressions. There is nothing to lose, and 
>> it should be easy to implement. This is what Java does. For
>> example, the following (which I found recently in JDT's code) is
>> perfectly legal Java code:
>>
>>   int length = array.length;
>>   ...
>>   System.arraycopy(array, 0, array = new IFoo[length + 1], 0, length);
>>
>> because Java not only defines that the argument evaluation order is left
>> to right, but also that the arguments are bound to parameters as they
>> are evaluated (and not after all are evaluated).
>>
>> The little details matter a lot.
> 
> 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)
> DMD's extern(D) (i.e. the default) calling convention and GDC's amd64 
> calling convention are a slight variation on that, passing some 
> arguments in a register if possible. It may for that reason be more 
> efficient to evaluate those in another order so that those registers can 
> be used in evaluation of other arguments.
> 
> 

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.

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.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D



More information about the Digitalmars-d mailing list