增量后运算符:意外行为

时间:2010-07-19 02:19:35

标签: c gcc post-increment

  

可能重复:
  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

这里发生了什么?海湾合作委员会试图拯救我自己吗?我没有方便的语言参考,但我认为这打破了预期的语义。

4 个答案:

答案 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的原因。