C中运算符的优先级和相关性
请查看以下代码段:
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草案 ),6.5p2:
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。 此外,先前的值应该是只读的,以确定要存储的值。
该表达式既读取a的值又更新它,并且读操作( +
的LHS)不用于确定写操作( +
的RHS)存储的值。
2011 ISO C标准(引自N1570草案 )对此有不同的说法 ,但含义基本相同:
如果对标量对象的副作用相对于对同一标量对象的不同副作用或使用相同标量对象的值进行的值计算未进行排序,则行为未定义。 如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的。
(a)
是使用a的值的值计算; (a++)
是对a的副作用。 由于未指定+
的操作数的评估顺序,因此这两个操作相对于彼此是无序的 。
因此,不仅仅是评估顺序未定义的问题 – 行为未定义,并且不限于在两个可能的顺序中评估的+
运算符的操作数的可能性。
不,括号不会改变这一点。
comp.lang.c FAQ的第3节很好地解释了这一点。
未指定+
的评估顺序。