D and expression evaluation order.

Bruno Medeiros brunodomedeiros+spam at com.gmail
Fri Apr 27 04:58:42 PDT 2007


Frits van Bommel wrote:
> 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...
> 

I haven't read about C++ in detail, only C. But in both cases (and 
sometimes here in the NG too) I often see the documents call "undefined 
behavior" to thing they should call errors. They refer to these concepts 
almost interchangeably, whereas they are not. They overlap a lot but 
they are not the same, there is a subtle difference.

Dereferencing a trash pointer, for example, *is* an error. It *causes* 
undefined behavior, but it *is not* merely undefined behavior: it *can 
crash* your program.
On the other hand if do:
   func(i++, i++);
where func simply prints prints its arguments, I will have undefined 
program behavior, but no program error : that code *can not ever* crash 
the program. (altough it is still likely a *conceptual* error)

This is a minor nitpick, since in practice both should be equally 
avoided, but that subtle difference is still there.


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

To "depend on the evaluation order" is to have the evaluation order 
matter. :)

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



More information about the Digitalmars-d mailing list