c++ - 赋值运算符内的序列点

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

我们以特定的复合赋值运算符^=为例。 This stackoverflow page表示在计算 ^= 后可能尚未完成对左操作数的修改,从而使代码 a ^= b ^= a ^= b 行为未定义。但事实似乎并非如此。该标准在 5.17 [expr.ass] 中表示

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.

这句话有两个要点。 1) 主题作业指的是什么?在我看来,它只是指左操作数的修改。 2) 赋值表达式的值计算指的是什么? cppreference说它指的是返回对修改对象的引用(强调我的)。

作为结论,在^=求值之后,左操作数应该已经被修改了,这与(大多数)人的想法相矛盾。我在这里遗漏了什么吗?

最佳答案

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

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

在那句话中:

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

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

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

  1. a 检索值和b (无论顺序),并确定存储结果的内存位置(分别计算右操作数和左操作数的值)

  2. 将结果存储在a中(分配)。涉及a ^ b的值计算,引文中没有提到,但显然必须在存储之前计算结果

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

你是对的,与你在纸上做事的顺序相比,2 和 3 看起来“倒退”。但请记住,一般来说,yx = y 的值不同。赋值表达式的值与 x 中存储的值相同。 (例如: int x; double y = (x = 6.5); - 那么 y6 ,而不是 6.5 )。因此,我们可以通过将结果存储在 a 中来做到这一点然后提供 a结果。

关于c++ - 赋值运算符内的序列点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29313902/

相关文章:

c++ - 是否存在 self 分配有用的情况?

c++ - 为什么像 "a[i] = i++;"这样的增量操作会导致未定义的行为?

c - 为什么这些构造使用增量前和增量后未定义的行为?

C++ 继承和赋值运算符

c++ - 程序中止挂起命名的互斥量

c++ - 与 2012 年相比,申请不断关闭

c++多线程代码设置不同线程的优先级

java - 对象1.toString() == 对象2.toString()

c - 为什么这些构造使用增量前和增量后未定义的行为?

c++ - 由于 '1300' 原因,循环未矢量化