Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this unspecified (undefined) behaviour or not?

Tags:

c++

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.

like image 217
Alexey Avatar asked Nov 12 '12 12:11

Alexey


2 Answers

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)

like image 188
Sergey K. Avatar answered Sep 23 '22 04:09

Sergey K.


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.

like image 22
Luchian Grigore Avatar answered Sep 21 '22 04:09

Luchian Grigore