为什么提到的代码是C中未定义的行为

时间:2013-06-18 15:31:21

标签: c c99

声明a[i]=i++;未定义,因为混淆了i(旧的或新的)用于评估左侧获取L-value的值。如果使用-Wall进行编译,此编译器会为此语句提供警告(操作..可能未定义)。

在下面的代码中,在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);
}

2 个答案:

答案 0 :(得分:12)

逗号运算符的优先级最低,

  

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

所以

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

实际上是

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

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

答案 1 :(得分:7)

x->a = x->b, ++x++->b;不会调用未定义的行为。逗号运算符的优先级低于赋值运算符,因此此代码等效于:

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

在第二行中,后缀++运算符正在修改x,前缀++运算符正在修改解除引用结构的成员b。没有违反序列点规则。