简体   繁体   English

C ++ 11中赋值运算符的副作用评估顺序

[英]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. 如果有人可以澄清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: cpprefence.com上评估顺序页面上的以下内容与作业有关:

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) 8)内置赋值运算符和所有内置复合赋值运算符的副作用(左参数的修改)在计算左参数和右参数的值(而不是副作用)之后进行排序,并且在赋值表达式的值计算之前排序(即,在将引用返回修改后的对象之前)

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? 何谓“(而不是副作用)?是副作用未测序测序inderminately或左参数的修改后测序 (甚至引用的归来后测序

As an example when do the post-increment operations take place in: while (*tgt++= *src++); 例如,何时在以下位置进行后递增操作:while(* tgt ++ = * src ++);

It seems clear from evaluation order that the value calculations are performed first, so *tgt and *src are calculated first. 评估顺序来看,显然首先执行值计算,因此首先计算*tgt*src But is it known when post-increment side effects occur? 但是是否知道增加后的副作用何时发生?

Edit #1: 编辑#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 . 实际上,这是我进入“兔子洞”的开始,最终使我进入了cppreference.com What I specifically want to know is the definition of sequencing of side effects for the assignment operator in C++11. 我特别想知道的是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 . 未定义的行为和顺序点中回答的问题是排序undefined ,未unspecied behaviourimpementation specific behaviour的概念之间的关系。 Which, by the way, it answers very well. 顺便说一句,它回答得很好。

End of Edit #1 编辑#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 . 首先,请注意,C ++ 17 对表达式求值顺序进行了相当多的更改

Let's first see what the current standard draft has to say. 首先让我们看看当前的标准草案有什么要说的。 I guess relevant here should be [intro.execution]/7 我想这里相关的应该是[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. […]对表达式(或子表达式)的评估通常包括值计算(包括确定对象的身份以进行glvalue评估和获取先前分配给对象的值以进行prvalue评估)和副作用的初始化。 […] [...]

and [intro.execution]/10 [介绍执行] / 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 最后是[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. *src的评估在*tgt的评估之前进行排序,而每个增量的副作用以及赋值都彼此无关。 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. 由于while循环中的条件完整表达式 ,因此在循环的一次迭代中发生的所有评估和副作用都将在下一次迭代的评估和副作用之前进行排序。

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. 据我所看到的, 在C ++ 11 ,所述的评价*src*tgt未测序相对于彼此而分配的副作用之前测序。 The side effects of the increments and the assignment were also unsequenced with respect to each other. 增量和分配的副作用彼此之间也没有顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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