puntero de la función C ++ Inlining
Pregunta
Sé que puedo pasar un puntero de función como parámetro de plantilla y obtener una llamada en línea, pero me pregunté si algún compilador en estos días puede en línea una función en línea 'obvia' como:
inline static void Print()
{
std::cout << "Hello\n";
}
....
void (*func)() = Print;
func();
Bajo Visual Studio 2008 es lo suficientemente inteligente como para obtener una instrucción de llamadas directas, por lo que parece una pena que no pueda dar un paso más allá.
Solución
El G ++ 4.5 de GNU lo inserta para mí comenzando en el nivel de optimización -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
donde .lc0 es el .String "Hola n".
Para comparar, sin optimización, G ++ -O0, no estaba en línea:
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq $_ZL5Printv, -8(%rbp)
movq -8(%rbp), %rax
call *%rax
movl $0, %eax
leave
ret
Otros consejos
Las versiones más nuevas de GCC (4.4 y más) tienen una opción llamada -Findirect -Inlining. Si el GCC puede demostrar a sí mismo que el puntero de la función es constante, entonces realiza una llamada directa a la función o ingresa la función por completo.
Bueno, el compilador realmente no sabe si esa variable se sobrescribirá en algún lugar o no (¿tal vez en otro hilo?), Por lo que se equivoca al lado de la precaución y la implementa como una llamada de función.
Acabo de registrar VS2010 en una compilación de lanzamiento y no se incluyó.
Por cierto, estás decorando la función como inline
es inútil. El estándar dice que si alguna vez obtiene la dirección de una función, cualquier inline
Sugerencia será ignorada.
editar: Sin embargo, tenga en cuenta que si bien su función no se ingresó, la variable se ha ido. En el desmontaje el call
Utiliza una dirección directa, no carga la variable en un registro y lo llama.