c ++函数指针内联

时间:2010-06-02 16:18:20

标签: c++ function pointers inlining

我知道我可以将函数指针作为模板参数传递并调用内联函数,但我想知道现在是否有任何编译器可以内联一个'明显'的内联函数,如:

inline static void Print()
{
 std::cout << "Hello\n";
}

....

void (*func)() = Print;

func();

在Visual Studio 2008中,它足够聪明,可以将其归结为直接调用指令,所以看起来很遗憾它不能再向前迈进了一步?

3 个答案:

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