我知道我可以将函数指针作为模板参数传递并内联调用它,但我想知道这些天是否有任何编译器可以内联一个“明显”的内联函数,例如:
inline static void Print()
{
std::cout << "Hello\n";
}
....
void (*func)() = Print;
func();
在 Visual Studio 2008 下,它足够聪明,可以将其归结为直接调用指令,所以它似乎很遗憾不能更进一步?
较新版本的 GCC(4.4 及更高版本)有一个名为 -findirect-inlining 的选项。如果 GCC 可以向自己证明函数指针是常量,那么它会直接调用该函数或完全内联该函数。
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
好吧,编译器并不真正知道该变量是否会在某个地方被覆盖(可能在另一个线程中?)所以它会谨慎行事并将其作为函数调用来实现。
我刚刚在发布版本中签入了 VS2010,但它没有被内联。
顺便说一句,您将功能装饰inline
为无用。该标准规定,如果您获得了函数的地址,则任何inline
提示都将被忽略。
编辑:但是请注意,虽然您的函数没有内联,但变量已消失。在反汇编中call
使用直接地址,它不会将变量加载到寄存器中并调用它。