此C代码会导致未定义行为吗?

我知道:

int b = 1, c = 2, d = 3, e = 4;
printf("%d %d %d", ++b, b, b++);

导致未定义的行为。自从

在两个序列点之间多次修改任何对象是 UB。
未定义的行为和序列点

但我不知道是否:

int b = 1, c = 2, d = 3, e = 4;
printf("%d", b++ + ++c - --d - e--);

也是UB吗?

我认为递增/递减运算符将首先评估,因为它们之间的优先级从右到左,因为 associativity 。然后算术运算符将从左到右计算。

这将是

(b) + (c + 1) - (d - 1) - (e)

即 1 + (2 + 1) - (3 - 1) - (4)

= (2 - 4)

= -2

这样对吗?

回答

但我不知道:...也是UB吗?

事实并非如此,但您对原因的推理是模糊的。

我认为增量/减量运算符将首先评估,因为它们之间的优先级从右到左,因为 associativity 。然后算术运算符将从左到右计算。

优先级决定了结果的计算方式。它没有说明副作用的排序。

没有等效的优先级告诉您在语句期间何时可以观察到副作用( 的存储值b已增加, 的存储值e已减少)。您所知道的是变量在下一个语句之前(即通过)采用了新值。;

因此,这是明确定义的原因是它不依赖于这些副作用


我故意挥舞着语言以避免陷入困境,但我可能应该澄清:

  • 在语句中”真正的意思是“在下一个序列点之前
  • 在下一个语句之前(... ;)”真正的意思是“在下一个序列点

请参阅评估顺序:

  1. 在对所有函数参数和函数指示符求值之后,在实际函数调用之前,有一个序列点。

所以实际上副作用是在调用 之前提交的printf,所以早于;语句末尾的 。


以上是此C代码会导致未定义行为吗?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>