闲来无事,做了一个inline函数的小实验。任何C++函数里面都说,inline函数会在调用体内展开。就做了一个实验:
首先,写了一个小程序。
#include <iostream>
using namespace std;
inline int test(int a){
return(a=a+1);
}
int main(){
int a=0;
a=test(a);
a=test(a);
cout<<a<<endl;
}
然后使用了g++ -g inline -o i.
再用objdump -d i
发现在main函数内
8048696: 8d 4c 24 04 lea 0x4(%esp),%ecx
804869a: 83 e4 f0 and $0xfffffff0,%esp
804869d: ff 71 fc pushl 0xfffffffc(%ecx)
80486a0: 55 push %ebp
80486a1: 89 e5 mov %esp,%ebp
80486a3: 51 push %ecx
80486a4: 83 ec 24 sub $0x24,%esp
80486a7: c7 45 f8 00 00 00 00 movl $0x0,0xfffffff8(%ebp)
80486ae: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
80486b1: 89 04 24 mov %eax,(%esp)
80486b4: e8 43 00 00 00 call 80486fc <_Z4testi>
80486b9: 89 45 f8 mov %eax,0xfffffff8(%ebp)
80486bc: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
80486bf: 89 04 24 mov %eax,(%esp)
80486c2: e8 35 00 00 00 call 80486fc <_Z4testi>
80486c7: 89 45 f8 mov %eax,0xfffffff8(%ebp)
80486ca: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
80486cd: 89 44 24 04 mov %eax,0x4(%esp)
80486d1: c7 04 24 d8 99 04 08 movl $0x80499d8,(%esp)
80486d8: e8 db fd ff ff call 80484b8 <_ZNSolsEi@plt>
80486dd: c7 44 24 04 28 85 04 movl $0x8048528,0x4(%esp)
80486e4: 08
80486e5: 89 04 24 mov %eax,(%esp)
80486e8: e8 2b fe ff ff call 8048518 <_ZNSolsEPFRSoS_E@plt>
80486ed: b8 00 00 00 00 mov $0x0,%eax
80486f2: 83 c4 24 add $0x24,%esp
80486f5: 59 pop %ecx
80486f6: 5d pop %ebp
80486f7: 8d 61 fc lea 0xfffffffc(%ecx),%esp
80486fa: c3 ret
80486fb: 90 nop
居然使用了函数call。call 80486fc <_Z4testi>
然后再试了一下g++ -O1 -g inline -o i.
这时候再看,发现没有了call
804864e: 8d 4c 24 04 lea 0x4(%esp),%ecx
8048652: 83 e4 f0 and $0xfffffff0,%esp
8048655: ff 71 fc pushl 0xfffffffc(%ecx)
8048658: 55 push %ebp
8048659: 89 e5 mov %esp,%ebp
804865b: 51 push %ecx
804865c: 83 ec 14 sub $0x14,%esp
804865f: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp)
8048666: 00
8048667: c7 04 24 58 99 04 08 movl $0x8049958,(%esp)
804866e: e8 15 fe ff ff call 8048488 <_ZNSolsEi@plt>
8048673: 89 04 24 mov %eax,(%esp)
8048676: e8 6d fe ff ff call 80484e8 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@plt>
804867b: b8 00 00 00 00 mov $0x0,%eax
8048680: 83 c4 14 add $0x14,%esp
8048683: 59 pop %ecx
8048684: 5d pop %ebp
8048685: 8d 61 fc lea 0xfffffffc(%ecx),%esp
而且优化的更好,直接mov了一个2进去。没有所说的代码膨胀问题。
那没有inline会怎样呢,尝试了没有inline的函数声明的,编译后。发现call依然存在。
目前发现,g++在O0的编译下,inline没有被展开,只是作为普通函数被调用。
在O1的编译下,发现inline函数没有被调用,而是被更优化的展开了。