1

If my C++ class has overloaded the bitwise-OR operator (|), does the C++ language spec guarantee that the arguments passed to a series of calls to that operator will be evaluated left-to-right? Or is the order-of-evaluation implementation-defined (or undefined)?

(IIRC C++'s built-in | operator has implementation-defined order-of-evaluation; but perhaps it is different when the operator has been overloaded for a class?)

Below is a program that exemplifies what I'm asking: Is this program guaranteed to print out 0 1 2 3 4 (as it does on the Mac I'm currently sitting at), or might it legally print out 4 3 2 1 0 (or some other ordering) in certain environments?

#include <iostream>

class mytype_t
{
public:
   mytype_t(int v) : _val(v) {/* empty */}

   mytype_t operator | (const mytype_t & rhs) const {return (_val | rhs._val);}

private:
   int _val;
};

mytype_t func(int v)
{
   std::cout << v << std::endl;
   return mytype_t(v);
}

int main(int, char **)
{
   mytype_t x = func(0) | func(1) | func(2) | func(3) | func(4);
   return 0;
}
Jeremy Friesner
  • 57,675
  • 12
  • 103
  • 196

1 Answers1

4

If the built in operator prescribes a specific sequencing, the arguments are evaluated in the same order for the overload as well. Here is the relevant paragraph (from n4659, the C++17 draft), emphasis mine:

[over.match.oper]

2 If either operand has a type that is a class or an enumeration, a user-defined operator function might be declared that implements this operator or a user-defined conversion can be necessary to convert the operand to a type that is appropriate for a built-in operator. In this case, overload resolution is used to determine which operator function or built-in operator is to be invoked to implement the operator. Therefore, the operator notation is first transformed to the equivalent function-call notation as summarized in Table 12 (where @ denotes one of the operators covered in the specified subclause). However, the operands are sequenced in the order prescribed for the built-in operator (Clause [expr]).

So no, the overloaded operator| will not have a well-defined evaluation order, because the built-in doesn't have one.

StoryTeller - Unslander Monica
  • 148,497
  • 21
  • 320
  • 399