我知道我可以将函数指针作为模板参数传递并接听它的呼叫,但是我想知道这些天是否有任何编译器可以将“显而易见”的内联函数插入:

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 使用直接地址,它不会将变量加载到寄存器中并调用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top