请看下面的代码片段:
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
b = (a) + (++a);
这有未定义的行为。
引用 C99 标准(实际上是 N1256 draft ),6.5p2:
Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression.
Furthermore, the prior value shall be read only to determine the value
to be stored.
这个表达式既读取了a
的值又更新了它,读取操作(+
的LHS)不用于确定要存储的值通过写操作(+
的RHS)。
2011 ISO C 标准(引用自 N1570 draft )对此有不同的表述,但含义基本相同:
If a side effect on a scalar object is unsequenced relative to either
a different side effect on the same scalar object or a value
computation using the value of the same scalar object, the behavior is
undefined. If there are multiple allowable orderings of the
subexpressions of an expression, the behavior is undefined if such an
unsequenced side effect occurs in any of the orderings.
(a)
是使用a
的值进行值计算; (a++)
是 a
的副作用。由于未指定 +
操作数的求值顺序,因此这两个操作相对于彼此未排序。
所以这不仅仅是求值顺序未定义的问题——行为是未定义的,并且不限于 +
操作数的可能性运算符以两种可能的顺序之一进行评估。
不,括号不会改变这一点。
comp.lang.c FAQ 的第 3 节很好地解释了这一点。