题
我知道我可以将函数指针作为模板参数传递并接听它的呼叫,但是我想知道这些天是否有任何编译器可以将“显而易见”的内联函数插入:
inline static void Print()
{
std::cout << "Hello\n";
}
....
void (*func)() = Print;
func();
在Visual Studio 2008下,它足够聪明,可以将其归结为直接通话指令,因此似乎可耻的是,它不能进一步进一步吗?
解决方案
GNU的G ++ 4.5嵌入IT为我开始,从优化级别-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
其他提示
GCC(4.4及以上)的较新版本具有名为-Findirect -Inlining的选项。如果GCC可以向自己证明该功能指针是恒定的,那么它可以直接调用该函数或完全嵌入函数。
好吧,编译器并不真正知道该变量是否会在某个地方覆盖(也许在其他线程中?),因此它在谨慎的侧面错误并将其作为函数调用。
我只是在发行版中检查了VS2010,但没有被嵌入。
顺便说一句,您将功能装饰为 inline
没用。标准说,如果您获得功能的地址,则 inline
提示将被忽略。
编辑: :请注意,尽管您的函数没有被绑定,但该变量已消失。在拆卸中 call
使用直接地址,它不会将变量加载到寄存器中并调用。
不隶属于 StackOverflow