встраивание указателя функции c++
Я знаю, что могу передать указатель функции в качестве параметра шаблона и получить вызов к нему встроенным, но мне было интересно, могут ли какие-либо компиляторы в наши дни встроить "очевидную" встроенную функцию, такую как:
inline static void Print()
{
std::cout << "Hellon";
}
....
void (*func)() = Print;
func();
В Visual Studio 2008 его достаточно умно, чтобы свести его к инструкции прямого вызова, так что, кажется, жаль, что он не может сделать шаг дальше?
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
использует прямой адрес, он не загружает переменную в регистр и вызывает ее.