gcc中的C副作用(前缀/后缀运算符和优先级)

Kap*_*pil 4 c gcc

我有小的C代码:

#include<stdio.h>
int main() 
{
    int  z[]= {1,2,3,4,5,6};
    int i = 2, j;
    printf("i=%d  \n",i); 

    z[i] = i++;

    for (j=0;j < 6;j++ )
       printf ("%d ", z[j]);

    printf("\ni=%d \n",i); 
}
Run Code Online (Sandbox Code Playgroud)

输出:

i=2  
1 2 2 4 5 6 
i=3
Run Code Online (Sandbox Code Playgroud)

评估表达式的优先顺序为首先,评估z [i]。当我在这里是2时,它变为z [2]。接下来,对i ++求值,即产生2且i变为3。最后,执行=,并将2(即从i ++产生的值)放入z [2]。

这解释了上面的输出,即1 2 2 4 5 6

但是如果我们将上面的代码从i ++更改为++ i即

#include<stdio.h>
int main() 
{
    int  z[]= {1,2,3,4,5,6};
    int i = 2, j;
    printf("i=%d  \n",i); 

    z[i] = ++i;

    for (j=0;j < 6;j++ )
       printf ("%d ", z[j]);

    printf("\ni=%d \n",i); 
}
Run Code Online (Sandbox Code Playgroud)

然后输出奇怪地不同,它是:

i=2  
1 2 3 3 5 6 
i=3
Run Code Online (Sandbox Code Playgroud)

如果我们遵循上述优先级(C规范说[index]早于++绑定),则输出应该是1 2 3 4 5 6。

我只想知道为什么上述优先顺序不能解释这一点?

我的编译器是Ubuntu 11.04上的gcc 4.5.2

感谢和问候,卡皮尔

Joh*_*ode 5

z[i] = ++i; 导致未定义的行为:

6.5表达式
...
2如果相对于相同标量对象上的不同副作用或使用相同标量对象的值进行的值计算,相对于标量对象的副作用未排序,则行为未定义。如果一个表达式的子表达式有多个允许的排序,则如果在任何排序中都发生这种无序的副作用,则行为是不确定的。84)
84)本段呈现未定义的语句表达式,例如

    i = ++i + 1;
    a[i++] = i;
Run Code Online (Sandbox Code Playgroud) 同时允许

    i = i + 1;
    a[i] = i;
Run Code Online (Sandbox Code Playgroud)

请注意,优先级仅控制运算符和操作数的分组;它不控制评估顺序。

所述的副作用++在操作者++i是未测序相对于[]操作者在z[i]; 编译器不需要以任何特定顺序求值两个表达式。还注意到,副作用的++i不被表达后立即应用的需要被评估; 它仅需要在下一个序列点之前应用。