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