看Chris对内联的总结,说到内联函数在编译时会被放入”符号表”,想一探究竟,结果却发现另外一个问题,疑惑不解。
1
2
3
4
5
6
7
| #include <stdio.h>
inline int add(int a, int b) { return a + b; }
int main()
{
int n = add(1,2);
return 0;
} |
1
2
| $ g++ -otest test.cpp
$ objdump ./test -d |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| 08048494 <main>:
8048494: 55 push %ebp
8048495: 89 e5 mov %esp,%ebp
8048497: 83 e4 f0 and $0xfffffff0,%esp
804849a: 83 ec 20 sub $0x20,%esp
804849d: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp)
80484a4: 00
80484a5: c7 04 24 01 00 00 00 movl $0x1,(%esp)
80484ac: e8 0b 00 00 00 call 80484bc <_Z3addii>
80484b1: 89 44 24 1c mov %eax,0x1c(%esp)
80484b5: b8 00 00 00 00 mov $0x0,%eax
80484ba: c9 leave
80484bb: c3 ret
080484bc <_Z3addii>:
80484bc: 55 push %ebp
80484bd: 89 e5 mov %esp,%ebp
80484bf: 8b 45 0c mov 0xc(%ebp),%eax
80484c2: 8b 55 08 mov 0x8(%ebp),%edx
80484c5: 8d 04 02 lea (%edx,%eax,1),%eax
80484c8: 5d pop %ebp
80484c9: c3 ret
80484ca: 90 nop
80484cb: 90 nop |
inline int add(int, int)没有内联,不解。另外,符号表里面也仅仅找到了_Z3addii,我不理解,干嘛把它放进符号表?我想这里的符号表不应该是熟知的那个符号表吧,应该只是编译期的一块用来inline的临时单元。
gcc -O2
优化后,什么main居然成空的了;-/:
080484a0
80484a0: 55 push %ebp
80484a1: 31 c0 xor %eax,%eax
80484a3: 89 e5 mov %esp,%ebp
80484a5: 5d pop %ebp
inline, 只是建议编译器把函数在调用处展开。至于是否展开,编译器说了算。
就像register一样,建议编译器把变量放到寄存器中,至于放不放,编译器说了算。
O2优化掉了dead code