I have read this article: Undefined behavior and sequence points, but i cannot figure, whether it is UB, or not.
Consider, following example:
#include <iostream>
class op {
public:
explicit op(int x) {
std::cout << "x: " << x << std::endl;
}
op & operator + (const op & /* other */) {
return *this;
}
};
int main(int /* argc */, char * /* argv */ []) {
int x = 0;
op o = op(x++) + op(x++) + op(x++);
std::cout << "res: " << x << std::endl;
return 0;
}
I expect output like this (or some permutation of output based on order of evaluation):
x: 0
x: 1
x: 2
res: 3
gcc-4.7.1 and clang-3.0 gives me such output, but when i compile this example with msvc-2010 i've got output:
x: 0
x: 0
x: 0
res: 3
Can you give me some information about this behaviour.
The order of arguments evaluation in a + b + c
is compiler-specific. Thus, the order of calls to x++
will be compiler-specific and relaying on it will be undefined behavior.
Using x++
or++x
in such expressions is usually a sign of bad coding standard. It is better to avoid it and simplify your expressions.
In this question Compilers and argument order of evaluation in C++ you can find a discussion on the order of arguments evaluation in C++.
Here is the explanation of C++ evaluation order with the references to C++ standard: http://en.cppreference.com/w/cpp/language/eval_order
P.S. Bjarne Stroustrup says it explicitly in "The C++ Programming Language" 3rd edition section 6.2.2. He also gives a reason:
Better code can be generated in the absence of restrictions on expression evaluation order.
(from https://stackoverflow.com/a/2934909/1065190)
It's undefined behavior because there's no sequence point between the post-increments of x
. You can't tell which +
will evaluate first, you can't tell which op(x++)
will be constructed first, and you can't tell in which order x++
will be executed. It's undefined, just don't write code like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With