#include <stdio.h> int main(void) { int i = 0; i = i++ + ++i; printf("%d\n", i); // 3 i = 1; i = (i++); printf("%d\n", i); // 2 Should be 1, no ? volatile int u = 0; u = u++ + ++u; printf("%d\n", u); // 1 u = 1; u = (u++); printf("%d\n", u); // 2 Should also be one, no ? register int v = 0; v = v++ + ++v; printf("%d\n", v); // 3 (Should be the same as u ?) int w = 0; printf("%d %d\n", ++w, w); // shouldn't this print 1 1 int x[2] = { 5, 8 }, y = 0; x[y] = y ++; printf("%d %d\n", x[0], x[1]); // shouldn't this print 0 8? or 5 0? }
C 具有未定义行为的概念,即某些语言结构在语法上是有效的,但您无法预测代码运行时的行为。
据我所知,该标准没有明确说明 为什么 存在未定义行为的概念。在我看来,这仅仅是因为语言设计者希望在语义上有一些余地,而不是要求所有实现都以完全相同的方式处理整数溢出,这很可能会带来严重的性能成本,他们只是离开了行为未定义,因此如果您编写导致整数溢出的代码,任何事情都可能发生。
那么,考虑到这一点,为什么会出现这些“问题”?该语言清楚地表明某些事情会导致未定义的行为。没有问题,不涉及“应该”。如果在声明涉及的变量之一时未定义的行为发生了变化volatile,那并不能证明或改变任何事情。它是 未定义 的;你无法对这种行为进行推理。
volatile
你最有趣的例子,那个
u = (u++);
是未定义行为的教科书示例(请参阅维基百科关于序列点的条目)。