可能重复:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
我的代码如下:
#include <stdio.h>
int main()
{
int x = 10, y = 0;
x = x++;
printf("x: %d\n", x);
y = x++;
printf("y: %d\n", y);
}
鉴于后增量的性质,我希望得到以下结果:
x: 10
y: 10
我的理由是,在第5行,x
应在增量发生后分配给它的初始值。
相反,我得到了这个:
x: 11
y: 11
进入大会,这对我来说是一个刻意的选择:
LCFI2:
movl $10, -4(%rbp) // this is x
movl $0, -8(%rbp) // this is y
incl -4(%rbp) // x is simply incremented
movl -4(%rbp), %esi
leaq LC0(%rip), %rdi
movl $0, %eax
call _printf
movl -4(%rbp), %eax // now x is saved in a register,
movl %eax, -8(%rbp) // copied to y,
incl -4(%rbp) // and finally incremented
movl -8(%rbp), %esi
leaq LC1(%rip), %rdi
movl $0, %eax
call _printf
这里发生了什么?海湾合作委员会试图拯救我自己吗?我没有方便的语言参考,但我认为这打破了预期的语义。
答案 0 :(得分:13)
行为未定义,因为x = x++
中没有插入序列点,例如, C FAQ。
答案 1 :(得分:4)
C语言未定义何时发生完全发布/进入/减少。因此,诸如x = x++
之类的陈述没有很好地形成 - 避免它们。
答案 2 :(得分:2)
除了标准(因为这与标准不一致),它的运行方式是我预期的方式。
我的经验法则是,对于包含x++
的行,您将x++
替换为x
,并将x += 1
放在下一行(或前一行)增量)。
遵循这条经验法则,您的代码将被写为
#include <stdio.h>
int main()
{
int x = 10, y = 0;
x = x; // x: 10
x += 1; // x: 11
printf("x: %d\n", x);
y = x; // y: 11
x += 1; // x: 12
printf("y: %d\n", y);
}
答案 3 :(得分:1)
当你有:
a = b++;
发生的事情是b被保存到a并且在完成分配之后b增加1。所以如果你这样做:
x = x ++;
以前x为10将会发生10将保存到x和之后(在你的printf完成之前)x增加1到11.这就是打印11的原因。