2

让我们以特定的复合赋值运算符为例^=这个stackoverflow页面说在评估之后可能没有对左操作数进行修改,^=从而使代码a ^= b ^= a ^= b未定义行为。但情况似乎并非如此。该标准在 5.17 [expr.ass] 中说

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

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

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

4

1 回答 1

3

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

此外,从 C11 和 C++11 开始,序列点不再存在;取而代之的是,排序为beforeunsequencedindetermined sequenced的关系存在。

在那句话中:

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

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

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

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

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

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

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

于 2015-03-28T06:06:40.407 回答