встраивание указателя на функцию c ++ - PullRequest
2 голосов
/ 02 июня 2010

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

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

....

void (*func)() = Print;

func();

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

Ответы [ 3 ]

2 голосов
/ 02 июня 2010

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 - это строка "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
2 голосов
/ 02 июня 2010

Более новые версии GCC (4.4 и выше) имеют опцию -findirect-inlining. Если GCC может доказать себе, что указатель функции является постоянным, то он делает прямой вызов функции или полностью указывает на функцию.

1 голос
/ 02 июня 2010

Что ж, компилятор на самом деле не знает, будет ли эта переменная где-то перезаписана или нет (может быть, в другом потоке?), Поэтому он ошибается и осторожно реализует ее как вызов функции.

Я только что зарегистрировался в VS2010 в сборке релиза, и он не стал встроенным.

Кстати, вы декорируете функцию как inline бесполезно. Стандарт гласит, что если вы когда-нибудь получите адрес функции, любая подсказка inline будет проигнорирована.

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

...