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

时间:2018-11-28 10:20:09

标签: c++ c++11

如果有人可以澄清C ++ 11中赋值语句的副作用排序,我将非常感激。例如,请指向与之相关的标准文字。

cpprefence.com上evaluation order上的页面说明了有关分配的以下内容:

  

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

“(不是副作用)是什么意思?在修改之后,未排序明确排序的排序的副作用是左引数的含义(或什至在引用返回后排序?)

作为示例,何时在以下位置进行后递增操作:     while(* tgt ++ = * src ++);

evaluation order可以看出,首先进行了值计算,因此首先计算了*tgt*src。但是是否知道增加后的副作用何时发生?

编辑#1:

Undefined behavior and sequence points尽我所能,没有回答我的问题。实际上,这是我进入“兔子洞”的开始,最终导致我进入cppreference.com。我特别想知道的是C ++ 11中赋值运算符的副作用的排序的定义。 Undefined behavior and sequence points中回答的问题是排序undefinedunspecied behaviourimpementation specific behaviour概念之间的关系。顺便说一句,它回答得很好。

编辑#1结束

最诚挚的问候

2 个答案:

答案 0 :(得分:1)

  

“(但不是副作用)是什么意思?

这句话强调了这样一个事实,即该句子没有要求对副作用进行排序。

  

在修改左引数之后(或者甚至在返回引用之后,是否会再排序)副作用是不确定的,不确定的排序还是排序?

这是在讨论每种特定副作用的段落中确定的。例如,后缀增量运算符的副作用在其值计算之后被排序,并且指出不确定顺序的函数调用不能干预。我找不到关于此操作符排序的其他主张。如果确实不存在,则必须得出结论,它是无序的。作业。

答案 1 :(得分:0)

首先,请注意C ++ 17引入了很多changes to expression evaluation order

首先让我们看看当前的标准草案有什么要说的。我想这里应该是[intro.execution]/7

  

[…]表达式(或子表达式)的评估通常包括值计算(包括确定对象的身份以进行glvalue评估和获取先前分配给对象的值以进行prvalue评估)和副作用的初始化。 […]

[intro.execution]/10

  

除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的求值是无序列的。 […]运算符的操作数的值计算在运算符结果的值计算之前进行排序。 […]

最后是[expr.ass]/1

  

[…]在所有情况下,赋值在左右操作数的值计算之后和赋值表达式的值计算之前进行排序。   右操作数在左操作数之前排序。 […]

基于此,我可以得出结论

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

*src的评估在对*tgt的评估之前进行排序,而每个增量的副作用以及赋值都彼此无关。由于while循环中的 condition full-expression,因此在循环的一次迭代中发生的所有评估和副作用都在下一次迭代的评估和副作用之前进行排序。

据我所知in C++ 11*src*tgt的评估相对于unsequenced而言,但在赋值的副作用之前进行了排序。增量和分配的副作用彼此之间也没有顺序。