相信很多学C/C++语言的兄弟并没有搞清象return X++这样的语句是怎么实现的。
如果你也像我一样,眼睛里容不得半点沙,那么,这篇文章就是为你所写的。
情况一:X是一简单类型
文件t.c内容如下:
int f(int a)
{
return a++;
}
int main()
{
int v = 1;
f(v);
return 0;
}
一般情况这种写法在c语言中其实没有任何意义,看一下转化成汇编的结果(用命令gcc -S t.c)
1 .file "t.c"
2 .text
3 .globl f
4 .type f, @function
5 f:
6 pushl %ebp
7 movl %esp, %ebp
8 movl 8(%ebp), %eax
9 incl 8(%ebp)
10 popl %ebp
11 ret
12 .size f, .-f
13 .globl main
14 .type main, @function
15 main:
16 pushl %ebp
17 movl %esp, %ebp
18 subl , %esp
19 andl $-16, %esp
20 movl , %eax
21 addl , %eax
22 addl , %eax
23 shrl , %eax
24 sall , %eax
25 subl %eax, %esp
26 movl , -4(%ebp)
27 movl -4(%ebp), %eax
28 movl %eax, (%esp)
29 call f
30 movl , %eax
31 leave
32 ret
33 .size main, .-main
34 .ident "GCC: (GNU) 4.0.0 (Gentoo Linux 4.0.0)"
35 .section .note.GNU-stack,"",@progbits
我们看函数f的实现。第八行把形参的值赋给寄存器%eax,linux下的AT&T汇编规定%eax中的内容是函数的返回值,这样就相当于直接把形参的返回了。而第九行的指令根本就没有作用,因为函数的形参是局部的auto变量,在函数的运行栈上分配空间。这样,即使在函数f中改变了形参的值,当函数返回后,这次改变就没有意义了。
可以看到,如果用-O优化的话,第九行的指令就被优化掉了。
命令gcc -S -O3 t.c的结果如下
1 .file "t.c"
2 .text
3 .p2align 4,,15
4 .globl f
5 .type f, @function
6 f:
7 pushl %ebp
8 movl %esp, %ebp
9 movl 8(%ebp), %eax
10 popl %ebp
11 ret
12 .size f, .-f
13 .p2align 4,,15
14 .globl main
15 .type main, @function
16 main:
17 pushl %ebp
18 xorl %eax, %eax
19 movl %esp, %ebp
20 subl , %esp
21 andl $-16, %esp
22 subl , %esp
23 leave
24 ret
25 .size main, .-main
26 .ident "GCC: (GNU) 4.0.0 (Gentoo Linux 4.0.0)"
27 .section .note.GNU-stack,"",@progbits