序列点与运算符优先级

可能重复:
非序列值计算(aka序列点)
未定义的行为和序列点
运营商优先级与评估顺序

我仍然试图围绕下面的表达式如何导致未定义的行为:

a = a++;

在搜索这个关于这个,我发现了以下问题:

序列点和运算符优先级之间的区别? 0_o

我通读了所有答案,但我仍然在细节上遇到困难。 其中一个答案将我上面的代码示例的行为描述为模糊,就a如何修改而言。 例如,它可以归结为以下两种情况之一:

a=(a+1);a++;
a++;a=a;

是什么让a的修改暧昧? 这是否与不同平台上的CPU指令有关,以及优化器如何利用未定义的行为? 换句话说,由于生成的汇编程序,它似乎未定义?

我没有看到编译器使用a=(a+1);a++; ,它看起来古怪,没有多大意义。 什么将拥有编译器,使其表现这种方式?

编辑:

为了清楚起见,我明白发生了什么事情,我不明白在有关运算符优先级(基本上定义了对表达式的评估顺序)的规则时,它是如何未定义的。 分配发生在最后这种情况下,这样a++需要被首先计算,以确定分配给值a 。 因此,我想到的是, a是第一改进,定位后增量中,但随后产生分配回值a (第二修改)。 但运营商优先权的规则似乎使我的行为非常清楚,我没有找到有什么“摆动空间”让它有未定义的行为。


您链接的问题中的第一个答案可以准确解释发生了什么。 我会试着重新修改它以使其更清楚。

运算符优先级定义了通过表达式计算值的顺序。 表达式(a++)的结果很好理解。

但是 ,变量a的修改不是表达式的一部分。 对真的。 这是您无法理解的部分,但这正是C和C ++如何定义它的。

表达式导致值,但是某些表达式可能有副作用。 表达式a = 1的值为1 ,但它也具有将变量a设置为1的副作用。 至于C和C ++如何定义事物,这是两个不同的步骤。 同样, a++有一个值和一个副作用。

序列点定义副作用何时对那些序列点之后评估的表达式可见。 运算符优先级与序列点无关。 这就是C / C ++如何定义事物。


这可能太简单了,但是我认为这是因为当代码用“a”完成时没有办法解决。 它是在增量还是赋值之后完成的? 决议最终呈圆形。 增量后的赋值改变了增量值应用的语义。 也就是说,代码不是用“a”完成的,直到“a”增加为止,但是a在赋值后才会增加。 这几乎是一个僵局的语言版本。

正如我所说,我相信这不是一个很好的“学术”解释,但这就是我在自己的耳朵之间收集的。 希望这有些帮助。


优先规则指定评估表达式的顺序,但在评估过程中不必发生副作用。 它们可以在下一个序列点之前的任何时候发生。

在这种情况下,增量的副作用在赋值之前和之后都没有排序,因此表达式具有未定义的行为。

链接地址: http://www.djcxy.com/p/73231.html

上一篇: Sequence Points vs Operator Precedence

下一篇: Prefix operator difference in C++ and C#