Question

I know I can pass a function pointer as a template parameter and get a call to it inlined but I wondered if any compilers these days can inline an 'obvious' inline-able function like:

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

....

void (*func)() = Print;

func();

Under Visual Studio 2008 its clever enough to get it down to a direct call instruction so it seems a shame it can't take it a step further?

Was it helpful?

Solution

GNU's g++ 4.5 inlines it for me starting at optimization level -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

where .LC0 is the .string "Hello\n".

To compare, with no optimization, g++ -O0, it did not inline:

main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    $_ZL5Printv, -8(%rbp)
    movq    -8(%rbp), %rax
    call    *%rax
    movl    $0, %eax
    leave
    ret

OTHER TIPS

Newer releases of GCC (4.4 and up) have an option named -findirect-inlining. If GCC can prove to itself that the function pointer is constant then it makes a direct call to the function or inlines the function entirely.

Well the compiler doesn't really know if that variable will be overwritten somewhere or not (maybe in another thread?) so it errs on the side of caution and implements it as a function call.

I just checked in VS2010 in a release build and it didn't get inlined.

By the way, you decorating the function as inline is useless. The standard says that if you ever get the address of a function, any inline hint will be ignored.

edit: note however that while your function didn't get inlined, the variable IS gone. In the disassembly the call uses a direct address, it doesn't load the variable in a register and calls that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top