2

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.

.

P.S.: My research so far...

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.

Community
  • 1
  • 1
paercebal
  • 81,378
  • 38
  • 130
  • 159
  • The two function calls are *indeterminately sequenced*: it means one occurs before the other, but it's not specified which one. As to the part that you find baffling: the rule effectively says that in `a=(b=c)`, the assignment to `b` happens before the assignment to `a` (the actual assignment is sequenced after both `a` and `b=c` are evaluated; and the value of `b=c` is computed after `b` is assigned). – Igor Tandetnik Nov 02 '14 at 00:47
  • @IgorTandetnik : Can you find the standard quote that makes the operands evaluation of `operator =` _indeterminately sequenced_? – paercebal Nov 02 '14 at 00:51
  • 1
    **1.9/15** Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced... Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function. – Igor Tandetnik Nov 02 '14 at 00:54
  • As of now, your comment arrived a bit after @Loopunroller, but it's more precise. Should you write an actual answer, I will really consider selecting it... :-) – paercebal Nov 02 '14 at 00:57
  • Actually, the answer depends on the nature of `A` and `B`. In your example, these look like classes, so `=` is not necessarily a built-in operator, but a call to overloaded `operator=`. This would render parts of section **5** you cite inapplicable. I presume this was not your intention? – Igor Tandetnik Nov 02 '14 at 01:01
  • Depending on what you answer is to @IgorTandetnik question about whether you intended this apply to classes or not then this may be a close to a duplicate: [Is `C == C++` undefined behaviour?](http://stackoverflow.com/q/25965372/1708801) – Shafik Yaghmour Nov 02 '14 at 01:52

1 Answers1

5

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.

Columbo
  • 60,038
  • 8
  • 155
  • 203