D and expression evaluation order.
Bruno Medeiros
brunodomedeiros+spam at com.gmail
Fri Apr 27 04:56:56 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 (altough it is still likely a
*conceptual* error) : that code *can not ever* crash the program.
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