14
votes

The comma operator guarantees left-to-right evaluation order.

[n3290: 5.18/1]: The comma operator groups left-to-right.

expression:
   assignment-expression
   expression , assignment-expression

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded value expression (Clause 5). Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand, and is a bit-field if its right operand is a glvalue and a bit-field.

The only other clause regarding the operator doesn't mention evaluation order. So it would appear that this is still the case when the operator has been overloaded.

But then, further up, in the general spiel regarding expressions, of course it is stated that the rules change when you overload operators:

[n3290: 5/2]: [ Note: Operators can be overloaded, that is, given meaning when applied to expressions of class type (Clause 9) or enumeration type (7.2). Uses of overloaded operators are transformed into function calls as described in 13.5. Overloaded operators obey the rules for syntax specified in Clause 5, but the requirements of operand type, value category, and evaluation order are replaced by the rules for function call. Relations between operators, such as ++a meaning a+=1, are not guaranteed for overloaded operators (13.5), and are not guaranteed for operands of type bool. —end note ]

However, this is non-normative text. Is there any normative text defining this rule, or could a compliant compiler ignore it?

1
In my mind, and according to Wikipedia, if the comma operator is overloaded it is simply replaced with a function call, and isn't the evaluation order of function call arguments implementation dependent? Which of course means that the right side may be evaluated first?Some programmer dude
@JoachimPileborg: Yes, but the question is, which normative passage in the standard specifies this? Neither your mind nor Wikipedia are authoritative, and you only stated what I already did. ;)Lightness Races in Orbit
Ah, sorry. I should stop reading advanced questions right after lunch! :)Some programmer dude
@JoachimPileborg: Lunch... now there's a good idea!Lightness Races in Orbit
Am I the only one who scratches my head wondering why the comma operator can be overloaded in the first place (rather than specifying that it always returns the type of the right hand operand)? Or, for that matter, wonders why the overloads "&&" and "||" are overloaded with a single function rather than a set of them used something like : "a && b" becomes "fn2(temp = fn1(a)) ? fn3(temp) : fn4(temp, b))", where the first parameter of fn2-fn4 must match the return type of fn1, and the needed compiler-temp variable would be auto-declared that type?supercat

1 Answers

10
votes

I only have the 03 standard to hand, but in it 5/3 says "Clause 5 defines the effects of operators when applied to types for which they have not been overloaded."

So all of clause 5, including 5.18/1, only applies to the built-in operators and not to any overloaded function.

(A compliant compiler could always evaluate the operands to an overloaded operator ,() left to right though.)