Reputation: 83374
In the following code:
A & getDataA() ;
B & getDataB() ;
void foo()
{
getDataA() = getDataB() ;
}
Is getDataA()
guaranteed to be evaluated before or after getDataB()
, or is the evaluation of both operands unsequenced one in relation to the other?
Note: I am interested by answers quoting the standard.
.
I tried to understand the standard to find the answer, and here is the result of my research. My understanding is that the evaluation of the two operands are unsequenced.
But... (every quote comes from C++14 draft n3797, 5.17 [expr.ass]):
The assignment operator (=) and the compound assignment operators all group right-to-left.
This means that the expression a = b = c ;
is really a = (b = c) ;
.
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
The first part says that for a = b ;
, the actual assignment will happen after a
and b
are evaluated. The second part baffles me: I can understand it for operator +=
(or another compound assignment operator), but I can't for operator =
.
Looking a the begining of the chapter (5 Expression [expr]), I read:
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.
This is what makes me believe the evaluations of the two operands are unsequenced (evaluations of function parameters are unsequenced, unless I missed something) for the cases where A
or B
are not built-ins.
But in the case above, A
and B
could be int
, so the built-in operator =
would be called, not a function.
Upvotes: 2
Views: 149
Reputation: 60999
Consider this text from §1.9:
Several contexts in C++ cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit. […] The sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.
This is specifically applied in the following quote from [expr]/2 (that you quoted yourself as well):
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.
Assuming that A
is a class, the assignment is an implicit call of its operator=
:
getDataA().operator=( getDataB() );
And according to a (non-normative) note from [expr.call]/8:
[ Note: The evaluations of the postfix expression and of the argument expressions are all unsequenced relative to one another. […] — end note ]
The normative text, which is found above the initial quote in this answer, includes this implicitly:
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
Nowhere is anything noted about the order of evaluation of the arguments and the postfix expression in a function call.
Upvotes: 5