2013-06-18 43 views
3

a[i]=i++;的声明是不确定的,因为有一个混淆,即i(旧的或新的)值用于评估左侧以获得L-value。如果使用-Wall进行编译,此编译器将给出警告(操作..可能未定义)。为什么在C中提到的代码是未定义的行为

在下面的代码,在声明中x->a = x->b, ++x++->b;
x正在被改变,并在左侧用它来获得L-value。对于这个语句,如果使用-Wall执行,编译器不会给出任何警告。

有人能解释为什么这不是未定义的行为? 谢谢!

struct Data { 
int a; 
int b; 
} y[4] = { 10, 20, 30, 40}; 

struct Data *x = y; 
int i; 

for(i=0; i<2; i++) { 
    x->a = x->b, ++x++->b; 
    printf("%d %d\t", y[i].a, y[i].b); 
} 
+5

仅仅因为编译器没有警告,并不意味着这个行为真的很好定义。 –

回答

12

逗号操作符具有最低的优先级,

表达:
赋值表达式
表达,赋值表达式

所以

x->a = x->b, ++x++->b; 

实际上是

(x->a = x->b), ++(x++->b); 

和逗号运算符是一个顺序点,因此两个修改x进行测序,并且没有未定义的行为。

+1

对,我错过了。如果语句x-> a = ++ x ++ - > b,它将是未定义的;谢谢 – mandeep

7

x->a = x->b, ++x++->b;不调用未定义的行为。逗号运算符具有比赋值操作符的优先级低,所以该代码相当于:

x->a = x->b; 
++x++->b; 

在第二行中出现,后缀++操作者修改x,并且前缀++操作者修改的构件b取消结构。没有序列点规则被侵犯。

+1

明确定义和明确的证明不一定是一回事。 – chepner

相关问题