赋值运算符中的序列点

时间:2015-03-28 05:09:52

标签: c++ assignment-operator sequence-points compound-assignment

让我们举个例子来说明特定的复合赋值运算符^=This stackoverflow page表示在评估^=之后可能尚未对左操作数进行修改,从而使代码a ^= b ^= a ^= b未定义为行为。但事实似乎并非如此。标准在5.17 [expr.ass]中说

  

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

本声明中有两个关键点。 1)主题赋值是指什么?在我看来,它仅指左操作数的修改。 2)赋值表达式的值计算是指什么? cppreference表示它返回对已修改对象的引用(强调我的)。

作为结论,在评估^=之后,左操作数应该已经被修改,这与大多数人的想法相矛盾。我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:2)

您链接到C问题。但是,这是无关紧要的,因为C和C ++是不同的语言。

此外,从C11和C ++ 11开始,序列点不再存在;相反,在未序列不确定序列之前,关系已经排序。

在那句话中:

  • 作业表示写入a的内存位置。
  • 表达式的
  • 值计算表示计算该表达式的值。 (示例 - 2 + 2的值为4,值计算是确定4是值的过程。

这里有两个值计算:a ^ ba =(结果)。

在引用的文字中,对于a = a ^ b,事情必须按此顺序发生:

  1. ab(以任意顺序)检索值,并确定存储结果的内存位置(分别为左右操作数的值计算)

  2. 将结果存储在a(作业)中。涉及a ^ b的值计算,在报价中没有提及,但显然必须在存储之前计算结果

  3. 执行赋值表达式的值计算。这意味着放弃存储在a中的值,准备好使用周围的表达式(值计算)。

  4. 你是对的,2和3似乎"向后"与您在纸上做事的顺序相比。但请记住,一般情况下,yx = y的值不同。赋值表达式的值与x中存储的值相同。 (示例:int x; double y = (x = 6.5); - 然后y6,而不是6.5)。因此,我们可以将结果存储在a中,然后提供a作为结果。