Search code examples
c++c++11standardschainingoperator-precedence

Chaining operation and order of evaluation on the same object


Consider a class MyClass with:

  • a member function myClass& myFunction1(int) that modifies the object and returns *this
  • a member function int myFunction2() const that does not modify the object

Does the C++11/14 standard guarantee that:

myclass.myFunction1(myclass.myFunction2()).myFunction1(myclass.myFunction2());

is equivalent to:

myclass.myFunction1(myclass.myFunction2());
myclass.myFunction1(myclass.myFunction2());

Solution

  • No. The compiler can first call myclass.myFunction2() twice and then do the two myFunction1 calls in the first example code. But not in the second example code.

    There is nothing that stops the compiler from sticking something in between the evaluation of function arguments and the call of the function. As long as the call actually happen after the evaluation of the call arguments (of that function). In Standardese terms

    When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function.

    Different expressions generally are unsequenced (unless there is explicit wording that sequences them). Your two calls to myclass.myFunction2 are such unsequenced cases, so that one of the calls to myclass.myFunction2 can appear after the other (and before the call to any of the myFunction1).