简体   繁体   中英

Evaluation order of side effects for assignment operator in C++11

I would very much appreciate it if someone could give a clarification on the sequencing of side effects for assignment statements in C++11. Eg, point me to the relevant standard text that deals with it.

The page on evaluation order on cpprefence.com states the following regarding assignments:

8) The side effect (modification of the left argument) of the built-in assignment operator and of all built-in compound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object)

What is meant by "(but not the side effects)? Are the side effects unsequenced , inderminately sequenced or sequenced after the modification of the left argument (or perhaps even sequenced after the returning of the reference?

As an example when do the post-increment operations take place in: while (*tgt++= *src++);

It seems clear from evaluation order that the value calculations are performed first, so *tgt and *src are calculated first. But is it known when post-increment side effects occur?

Edit #1:

Undefined behavior and sequence points does to my best understanding not answer my question. In fact it was the start of my descent into the "rabbit hole" that in the end led me to cppreference.com . What I specifically want to know is the definition of sequencing of side effects for the assignment operator in C++11. The question answered in Undefined behavior and sequence points is the relation between sequencing and the concepts of undefined , unspecied behaviour and impementation specific behaviour . Which, by the way, it answers very well.

End of Edit #1

Best regards

What is meant by "(but not the side effects)?

This remark emphasises the fact that the sentence makes no claims about sequencing of side effects.

Are the side effects unsequenced, inderminately sequenced or sequenced after the modification of the left argument (or perhaps even sequenced after the returning of the reference?

This is determined in paragraphs that discuss each specific side effect. For example, the side effect of the postfix increment operator is sequenced after its value computation, and it is stated that an indeterminately-sequenced function call cannot intervene. There are no other claims made about sequencing of this operator that I can find. If there are indeed none, one must conclude it is unsequenced wrt the assignment.

First of all, note that C++17 introduced quite some changes to expression evaluation order .

Let's first see what the current standard draft has to say. I guess relevant here should be [intro.execution]/7

[…] Evaluation of an expression (or a subexpression) in general includes both value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and initiation of side effects. […]

and [intro.execution]/10

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. […] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. […]

and finally [expr.ass]/1

[…] 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 right operand is sequenced before the left operand. […]

Based on this, I would conclude that in

while (*tgt++ = *src++);

the evaluation of *src is sequenced before the evaluation of *tgt while the side-effects of each increment as well as the assignment are all unsequenced with respect to each other. Since the condition in a while loop is a full-expression , all evaluations and side effects occurring in one iteration of the loop are sequenced before the evaluations and side effects of the next iteration.

As far as I can see, in C++ 11 , the evaluations of *src and *tgt were unsequenced with respect to each other but sequenced before the side effect of assignment. The side effects of the increments and the assignment were also unsequenced with respect to each other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM