
c++对内联优化的处理是个很重要的知识点,对这个问题的考虑来自这个帖子:
,其中涉及的另一个链接,提到了Java在运行时对多态函数的内联优化。
在c++中通过基类指针调用的多态函数是无法被内联优化的,因为基类指针实际指向的对象是基类还是子类是在运行时才能确定的,因此是无法被内联化的。
需要注意的是,造成无法内联化的不是多态或者继承本身,根本原因是在于静态编译条件下对函数指针的调用无法定位到静态代码地址,因此无法将用函数指针来进行函数调用的地方用所调用代码内联化。
举个例子:
void fn1(){
}
void fn2(){
}
int main(){
void (*pf)(void);
for(int i=0;i<1000;i++) {
if(i>20) {
pf=&fn1;
}else{
pf=&fn2;
}
(*pf)();
}
}
在gcc O0下生成的汇编如下:
main.o: file format pe-i386 Disassembly of section .text: 00000000 <__Z3fn1v>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: c9 leave 4: c3 ret 00000005 <__Z3fn2v>: 5: 55 push %ebp 6: 89 e5 mov %esp,%ebp 8: c9 leave 9: c3 ret 0000000a <_main>: a: 55 push %ebp b: 89 e5 mov %esp,%ebp d: 83 e4 f0 and $0xfffffff0,%esp 10: 83 ec 10 sub $0x10,%esp 13: e8 00 00 00 00 call 18 <_main+0xe> 18: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) //初始化i 1f: 00 20: eb 23 jmp 45 <_main+0x3b> 22: 83 7c 24 08 14 cmpl $0x14,0x8(%esp) //比较i和20大小 27: 7e 0a jle 33 <_main+0x29> 29: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) //函数fn1地址赋予pf 30: 00 31: eb 08 jmp 3b <_main+0x31> 33: c7 44 24 0c 05 00 00 movl $0x5,0xc(%esp) //函数fn2地址赋予pf 3a: 00 3b: 8b 44 24 0c mov 0xc(%esp),%eax 3f: ff d0 call *%eax //通过函数指针pf调用函数 41: ff 44 24 08 incl 0x8(%esp) 45: 81 7c 24 08 e7 03 00 cmpl $0x3e7,0x8(%esp) 4c: 00 4d: 0f 9e c0 setle %al 50: 84 c0 test %al,%al 52: 75 ce jne 22 <_main+0x18> 54: b8 00 00 00 00 mov $0x0,%eax 59: c9 leave 5a: c3 ret 5b: 90 nop
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-34432-1.html
不过再怎么作死