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