此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已减少)。您所知道的是变量在下一个语句之前(即通过)采用了新值。;
因此,这是明确定义的原因是它不依赖于这些副作用。
我故意挥舞着语言以避免陷入困境,但我可能应该澄清:
- “在语句中”真正的意思是“在下一个序列点之前”
- “在下一个语句之前(...
;)”真正的意思是“在下一个序列点”
请参阅评估顺序:
- 在对所有函数参数和函数指示符求值之后,在实际函数调用之前,有一个序列点。
所以实际上副作用是在调用 之前提交的printf,所以早于;语句末尾的 。