该陈述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);
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*her 12
逗号运算符的优先级最低,
表达式:
赋值表达式
表达式,赋值表达式
所以
x->a = x->b, ++x++->b;
Run Code Online (Sandbox Code Playgroud)
实际上是
(x->a = x->b), ++(x++->b);
Run Code Online (Sandbox Code Playgroud)
并且逗号运算符是一个序列点,因此对这两个修改进行x排序,并且没有未定义的行为.
x->a = x->b, ++x++->b;不会调用未定义的行为.逗号运算符的优先级低于赋值运算符,因此此代码等效于:
x->a = x->b;
++x++->b;
Run Code Online (Sandbox Code Playgroud)
在第二行中,后缀++运算符正在修改x,前缀++运算符正在修改b解除引用结构的成员.没有违反序列点规则.