встраивание указателя функции c++


Я знаю, что могу передать указатель функции в качестве параметра шаблона и получить вызов к нему встроенным, но мне было интересно, могут ли какие-либо компиляторы в наши дни встроить "очевидную" встроенную функцию, такую как:

inline static void Print()
{
 std::cout << "Hellon";
}

....

void (*func)() = Print;

func();

В Visual Studio 2008 его достаточно умно, чтобы свести его к инструкции прямого вызова, так что, кажется, жаль, что он не может сделать шаг дальше?

3 2

3 ответа:

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

Где. LC0-это .строка "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 будет проигнорирована.

Edit : обратите внимание, однако, что пока ваша функция не была встроена, переменная исчезла. В дизассемблировании call использует прямой адрес, он не загружает переменную в регистр и вызывает ее.