D and expression evaluation order.

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Thu Apr 26 04:25:12 PDT 2007


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++.

> 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.


[1] Though on amd64 the first few arguments are typically passed in 
registers, and DMD by default passes one argument in a register as well, 
so the stack may not be used if there are few arguments.



More information about the Digitalmars-d mailing list