我知道我可以将函数指针作为模板参数传递并调用内联函数,但我想知道现在是否有任何编译器可以内联一个'明显'的内联函数,如:
inline static void Print()
{
std::cout << "Hello\n";
}
....
void (*func)() = Print;
func();
在Visual Studio 2008中,它足够聪明,可以将其归结为直接调用指令,所以看起来很遗憾它不能再向前迈进了一步?
答案 0 :(得分:2)
GNU的g ++ 4.5从优化级别-O1
开始为我编写main:
subq $8, %rsp
movl $6, %edx
movl $.LC0, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_E
movl $0, %eax
addq $8, %rsp
ret
其中.LC0是.string“Hello \ n”。
要比较,没有优化,g ++ -O0,它没有内联:
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq $_ZL5Printv, -8(%rbp)
movq -8(%rbp), %rax
call *%rax
movl $0, %eax
leave
ret
答案 1 :(得分:2)
较新版本的GCC(4.4及更高版本)有一个名为-findirect-inlining的选项。如果GCC可以向自己证明函数指针是常量的,那么它会直接调用函数或完全内联函数。
答案 2 :(得分:1)
编译器真的不知道该变量是否会在某处被覆盖(可能在另一个线程中?)所以它会在谨慎方面出错,并将其作为函数调用实现。
我刚刚在发布版本中检查了VS2010并且没有内联。
顺便说一句,你将函数装饰为inline
是没用的。标准说如果你得到一个函数的地址,任何inline
提示都将被忽略。
编辑:请注意,虽然您的函数没有内联,但变量IS消失了。在反汇编中,call
使用直接地址,它不会将变量加载到寄存器中并调用它。