1

请看下面的代码片段:

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
4

2 回答 2

8
b = (a) + (++a);

这具有未定义的行为。

引用 C99 标准(实际上是N1256 草案),6.5p2:

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,应仅读取先验值以确定要存储的值。

该表达式既读取 的值a又更新它,读取操作( 的 LHS +)不用于确定写入操作( 的 RHS +)要存储的值。

2011 ISO C 标准(引自N1570 草案)对此有不同的表述,但含义基本相同:

如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用相同标量对象的值的值计算是未排序的,则行为未定义。如果表达式的子表达式有多个允许的排序,则如果在任何排序中出现这种未排序的副作用,则行为未定义。

(a)是使用 的值进行的值计算a(a++)是对 的副作用a+由于未指定的操作数的求值顺序,因此这两个操作相对于彼此是无序的。

因此,这不仅仅是评估顺序未定义的问题——行为未定义,并且不限于以+两种可能顺序中的任何一种评估运算符的操作数的可能性。

不,括号不会改变这一点。

comp.lang.c FAQ的第 3 节很好地解释了这一点。

于 2013-05-13T20:05:45.640 回答
3

的评估顺序 +未指定。

于 2013-05-13T20:00:47.863 回答