C ++ operator priority shift

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(); 

It is strange that the compiler generates code that evaluates intResult1 BEFORE intResult0 (tested with the latest VC and gcc). Why would the compiler do this? Thus, the time between evaluating and using the appropriate values ​​(unnecessarily) increases (?), That is, 42 is selected first, and then returns the latter to the vector. Does this define the C ++ standard?

+4
source share
4 answers

According to article 6.2.2 of the Stroustrup:

The procedure for evaluating a subexpression in an undefined expression.

+12
source

The order in which subexpressions are evaluated between two points in a sequence is undefined.

The above code is syntactic sugar for:

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

The only limitation that the compiler has is that it must evaluate all parameters before calling the method and obey priority rules. But as long as it follows these rules, each implementation is allowed to choose the details, and therefore this order may vary between compilers.

In this example:

  • Thus, it is quite normal to call intResult1 () before intResult2 ().
  • But intResult0 () must be called before calling the operator <(lt () (left)
  • and intResult1 () must be called before calling the operator <(lt; () (on the right)
  • and the operator <() (on the left) should be called before the operator <(lt () (on the right)

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

and

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

+14
source

This has nothing to do with priority.

There is no sequence point in this last statement, so the compiler can freely evaluate subexpressions in any order if it is used when combining subexpressions.

Please note that priority does not determine the general order of evaluation - it simply determines how expression operands will be combined with several operators.

For example, in the following expression:

 a() * b() + c() 

at some point, the compiler will have to evaluate (a() * b()) before adding the result of c() , but nothing is said about what order each individual function call should perform. The compiler can easily decide to call c() , push the result on the stack, and then do whatever it needs to evaluate the expression (a() * b()) (in this case, it can decide to evaluate b() first

The only role that priority plays is that the compiler is not allowed to evaluate the expression as:

 a() * (b() + c()) 
+10
source

C ++ Standard, 5: 4

Except where noted, the order of evaluation of the operands of individual operators and subexpressions of individual expressions and the order in which side effects occur

+2
source

Source: https://habr.com/ru/post/1286234/


All Articles