Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ shift operator precedence weirdness

Consider the following code:

typedef vector<int> intVec;

intVec& operator<<(intVec& dst, const int i) {
    dst.push_back(i);
    return dst;
}
int intResult0() {
    return 23;
}
int intResult1() {
    return 42;
}

// main
intVec v;
v << intResult0() << intResult1();

The weird thing is, that the compiler generates code, which evaluates intResult1 BEFORE intResult0 (tested with newest VC und gcc). Why would the compiler do this? By doing so, the time between evaluation and usage of the respective values is (unnecessarily) increased(?), i.e. 42 is fetched first, but pushed last to the vector. Does the C++ standard dictate this?

like image 775
newgre Avatar asked Nov 28 '22 00:11

newgre


1 Answers

The order of evaluation of sub-expressions between two sequence point is undefined.

The above code is syntactic sugar for:

v.operator<<(intResult0()).operator<<(intResult1());

The only constraint the compiler has, is that it must evaluate all parameters before a method is called and obey the precedence rules. But as long as it follows these rules each implementation is allowed to choose the details and as such this order may change between compilers.

In this example:

  • So it is perfectly legal to call intResult1() before intResult2().
  • But intResult0() must be called before the call to operator<<() (left)
  • and intResult1() must be called before the call to operator<<() (right)
  • and operator<<() (left) must be called before operator<<() (right)

See here for more info:
What are all the common undefined behaviours that a C++ programmer should know about?

and

What are all the common undefined behaviours that a C++ programmer should know about?

like image 57
Martin York Avatar answered Dec 05 '22 02:12

Martin York