今天上课,忽然同学和我讨论一个问题。
问题:C/C++ 中的代码 { int x = 1; x = x++; } 的结果x是多少?
围绕这个问题,我们完全忽略老师的讲课,在教室尾展开简单的讨论。。。
首先,对于问题来说,得出的结果可以是 x = 1,也可以是 x =2.
(主要看环境。linux 64 gcc/g++ 测试得到 x = 1)
我们就直接讨论一下,为什么在linux 64 下,得到 x = 1 。
在解析之前,我们先看下这个情况。
int
main(void){
int x = 1,b = 0;
b = x++;
printf("%d\n" , x);
printf("%d\n" , b);
return 0;
}
输出:
2 , 1
这个应该没啥问题吧。(x赋值给b,然后x自增)
我们深入看一下,b = x++,C/C++编译器是怎么处理的。
看汇编码:
.LFB0:
.......
movl $1, -4(%rbp)
movl $0, -8(%rbp)
movl -4(%rbp), %eax
leal 1(%rax), %edx
movl %edx, -4(%rbp)
movl %eax, -8(%rbp)
movl -4(%rbp), %eax
......
x的值先存入寄存器%eax(值为1) , 然后a + 1 的值存入寄存器 %edx(值为2) 。 操作完毕,然后 %edx 赋值给 x , %eax 赋值给 b。
所以,这里用到了两个寄存器来实现计算。
然后,我们看下这个:
int
main(void){
int x = 1;
x = x++;
printf("%d\n" , x);
return 0;
}
上汇编:
.LFB0:
......
movl $1, -4(%rbp)
movl -4(%rbp), %eax
leal 1(%rax), %edx
movl %edx, -4(%rbp)
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
......
情况和上面一样,区别是,寄存器%eax刷新了%edx赋值的结果。所以,导致 x = 1。
所以,问题的结果是 x = 1
其实。对于
x = x++
x += -= x * x
这类坑爹的写法,按照上面的分析,知道大概内部实现的策略,就很容易思考出结果。
(以上测试在gcc/g++ 4.8.2 环境下测试)