请查看以下代码段:
int a = 10, b;
b = (a) + (++a); //2
printf("b = %d\n", b);
输出:
b = 22
在声明2中,有4个不同的运算符。其中()
具有最高优先级。由于()
运算符的关联性是从左到右为什么b = 22
而不是21
?
$ gcc --version
gcc (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3
答案 0 :(得分:8)
b = (a) + (++a);
这有不明确的行为。
引用C99标准(实际上是N1256 draft),6.5p2:
在前一个和下一个序列点之间,一个对象应该具有它 通过表达式的评估,最多修改一次存储值。 此外,先前的值应只读以确定该值 存储。
此表达式都读取a
的值并更新它,并且读操作(+
的LHS)不用于确定写操作要存储的值( +
)的RHS。
2011 ISO C标准(引自N1570 draft)的说法不同,但含义基本相同:
如果标量对象的副作用相对于其中任何一个都没有排序 对同一个标量对象或值有不同的副作用 使用相同标量对象的值进行计算,行为是 未定义。如果有多个允许的排序 表达式的子表达式,如果这样的话,行为是不确定的 任何顺序都会出现无序的副作用。
(a)
是使用a
的值进行的值计算; (a++)
是a
的副作用。由于未指定+
操作数的评估顺序,因此这两个操作相对于彼此未排序。
因此,不仅仅是评估顺序未定义的问题 - 行为未定义,并且不限于被评估的+
运算符的操作数的可能性在两个可能的订单中的任何一个。
不,括号不会改变这一点。
comp.lang.c FAQ的第3节解释了这一点。
答案 1 :(得分:3)
未指定+
的评估顺序。