Search code examples
c++c++17evaluation

C++: What is the evaluation order of the user-defined comma operator?


I was reading the "C++ 17 Completed Guide" by Nicolai Josuttis and came across the following expression:

foo(arg1), (foo(arg2), foo(arg3));

The author claims that the evaluation order will be left to right for the built-in comma operators, but it can be changed by overloading them. However, I saw the "Order of evaluation" article on cppreference (https://en.cppreference.com/w/cpp/language/eval_order) and came across the following statements:

  1. Every value computation and side effect of the first (left) argument of the built-in comma operator , is sequenced before every value computation and side effect of the second (right) argument.

and

  1. Every overloaded operator obeys the sequencing rules of the built-in operator it overloads when called using operator notation.

So, according to the statement 16, it appears that cppreference claims the overloaded comma operator to have the same evaluation order as its built-in counterpart. So, what exactly did the author mean by saying that "by overloading the comma operator, you can change its evaluation order" and what exactly behavior is expected?


Solution

  • Evaluation order was a mess prior to C++17. C++17 made sweeping changes to evaluation order, this is most likely just a mistake by the author.

    Prior to C++17, overloaded operators are complete syntax sugar. With any binary operator @, a@b is equivalent to one of

    operator@(a, b)
    a.operator@(b)
    

    depending on whether it is a member function or free function. Which is to say, a and b are unsequenced relative to each other

    In C++17 the evaluation order of a@b is the same as the built-in operators. For the comma operator, a is sequenced before b. In the function call version, a and b are indeterminately sequenced.