赋值运算符中的序列点 [英] Sequence point within assignment operators

查看:142
本文介绍了赋值运算符中的序列点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们举个具体的复合赋值运算符 ^ = 此stackoverflow页面说可以在 ^ = 的评估之后未进行左操作数的修改,并且因此使得代码 a ^ = b ^ = a ^ = b 未定义的behaivor。但这似乎不是这样的。标准在5.17 [expr.ass]中说明


在所有情况下,赋值在计算


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



作为结论,左操作数应该已经在 ^ = ,这是一个矛盾的(大多数)人的想法。我在这里缺少什么?

解决方案

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



此外,截至C11和C ++ 11的序列点不再存在; 以及不确定顺序之间的关系



意味着写入 a 的内存位置:

  • 值计算表示计算该表达式的值。 (示例 - 2 + 2 的值为 4 ,值计算是确定<$



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



    在引用的文本中, 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); - then y is 6 ,而不是 6.5 )。因此,我们可以通过将结果存储在 a 中,然后提供 a 作为结果。


    Let's just take for example the specific compound assignment operator ^=. This stackoverflow page says modification of the left operand may have not been done after the evaluation of ^=, and thus making the code a ^= b ^= a ^= b undefined behaivor. But this does not seem to be the case. The standard says in 5.17 [expr.ass] that

    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.

    There are two keypoints in this statement. 1) What does the subject assignment refers to? In my opinion, it refers just to the modification of the left operand. 2) What does value computation of the assignment expression refers to? cppreference says it refers to returning the reference to the modified object (emphasis mine).

    As a conclusion, the left operand should have already been modified after the evaluation of ^=, which is a contradiction to what (most) people think. Am I missing something here?

    解决方案

    You link to a C question. However, this is irrelevant as C and C++ are different languages.

    Also, sequence points no longer exist as of C11 and C++11; instead the relations sequenced before, unsequenced, and indeterminately sequenced exist.

    In that quote:

    • the assignment means the write to the memory location of a.
    • value computation of an expression means the computation of the value of that expression. (Example - the value of 2 + 2 is 4, and the value computation is the process of determining that 4 was the value).

    There are two value computations here: a ^ b, and a = (that result).

    In the quoted text, for a = a ^ b, things must occur in this order:

    1. Retrieve values from a and b (in either order), and determine the memory location in which to store the result (value computation of right and left operand, respectively)

    2. Store the result in a (the assignment). The involves value computation of a ^ b, which isn't mentioned in the quote but clearly the result must be calculated before it is stored

    3. Perform value computation of the assignment expression. This means yielding up the value stored in a ready for a surrounding expression to use (value computation).

    You're right that 2 and 3 seem "backwards" compared to the order you might do things on paper. But remember that in general, y is different to the value of x = y. The value of the assignment expression is the same as the value stored in x . (Example: int x; double y = (x = 6.5); - then y is 6, not 6.5). So we can do this by storing the result in a and then offering a as the result.

    这篇关于赋值运算符中的序列点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆