2009-06-01 19 views
17

He estado probando llamadas a funciones en línea en C++.C++ funciones en línea usando GCC - ¿por qué la LLAMADA?

Thread model: win32 
gcc version 4.3.3 (4.3.3-tdm-1 mingw32) 

BS en el directorio C++ wirtes lenguaje de programación:

El comitente en línea es una sugerencia para el compilador que se debe tratar de generar el código [...] en línea en lugar de que se establece el código para la función una vez y luego llamar a través del mecanismo de llamada de función habitual.

Sin embargo, he descubierto que el código generado simplemente no está en línea. Hay un CALL instrction para la función isquare.

alt text http://i42.tinypic.com/8ys3f4.jpg

Por qué sucede esto? ¿Cómo puedo usar las funciones en línea?

EDIT: Las opciones de línea de comandos usados:

**** Build of configuration Debug for project InlineCpp **** 

**** Internal Builder is used for build    **** 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc\InlineCpp.o ..\src\InlineCpp.cpp 
g++ -oInlineCpp.exe src\InlineCpp.o 
+1

¿Ha comprobado qué código se genera cuando sube el nivel de optimización? Además, intente agregar el parámetro '-finline-functions' al compilar el código – Christoph

+2

. Publique las opciones de línea de comando que usó con gcc para compilar el código. (Si no está utilizando una de las funciones -O3 o -finline, entonces gcc ignorando "en línea" no me sorprende). – timday

+3

el problema es el -O0 que tiene en los indicadores del compilador, lo que significa ** no ** optimizaciones. Cambie eso a -O2 y estará perfectamente alineado. –

Respuesta

22

No hay manera genérica C++ para obligar al compilador para crear funciones en línea. Tenga en cuenta la palabra 'sugerencia' en el texto que citó: el compilador no está obligado a escucharlo.

Si realmente, absolutamente tiene que hacer que algo esté en línea, necesitará una palabra clave específica del compilador O tendrá que usar macros en lugar de funciones.

EDITAR: njsf da la palabra clave correcta de gcc en su respuesta.

0

Si en línea depende del compilador. Es libre de ignorar el en línea pista. Algunos compiladores tienen una palabra clave específica (como __forceinline en VC++) pero incluso con una palabra clave así, las llamadas virtuales a las funciones de miembros virtuales no estarán en línea.

3

Es una sugerencia y el compilador puede optar por ignorar la sugerencia. Creo que leí algo en que GCC generalmente lo ignora. Recuerdo haber escuchado que había una bandera, pero todavía no funciona en el 100% de los casos. (No he encontrado un enlace todavía).

Marcador: -finline-functions se enciende a -O3 nivel de optimización.

+3

Creo que la principal diferencia que paga gcc para "en línea" es que significa que la función puede tener hasta 600 instrucciones grandes y seguir ingresando, mientras que las funciones no declaradas en línea consideradas para la alineación automática con -funciones -fin tienen que ser menores a 300 instrucciones. Puede jugar con todos estos números y más usando --param para ajustar cosas con nombres como max-inline-insns-auto (pero necesita una buena razón para hacerlo; los valores predeterminados son de sonido). Sin embargo, cambiar la diferencia entre los números de enlining explícito y automático significa que efectivamente puede hacer que inline tenga más o menos un efecto. – timday

+0

Eso es muy interesante. Gracias. –

47

Como mencionó Michael Kohne, la palabra clave en línea es siempre una pista, y GCC en el caso de su función decidió no encuadrarla.

Dado que está utilizando Gcc, puede forzar el alineamiento con el atributo __ ((always_inline)).

Ejemplo:

/* Prototype. */ 
inline void foo (const char) __attribute__((always_inline)); 

Fuente: GCC inline docs

+0

upvoted para el gcc-fu –

+5

Sí, pero si el interrogador se va y empieza a pegar __attribute __ ((always_inline)); en todas sus funciones en lugar de simplemente compilar con -O3, hemos fallado. – timday

+2

De acuerdo. Creo que todavía soy optimista y creo que la mayoría de la gente tiene sentido común ;-) – njsf

8

¿Usted está mirando una versión de depuración (optimizaciones desactivado)? Los compiladores generalmente desactivan la creación en compilaciones de "depuración" porque dificultan la depuración.

En cualquier caso, el inline especificado es de hecho un pista. El compilador no está obligado a alinear la función. Hay una serie de razones por cualquier compilador puede decidir ignorar una sugerencia en línea:

  • Un compilador puede ser muy sencilla, y es compatible con inlining
  • Un compilador puede utilizar un algoritmo interno para decidir sobre qué línea y ignora los consejos.
    (a veces, el compilador puede hacer un mejor trabajo de lo que puedes hacer en la elección de qué línea, especialmente en arquitecturas complejas como IA64)
  • Un compilador podría utilizar sus propios heurística para decidir que a pesar de la pista, inlining no mejorará el rendimiento
4

Inline no es más que una sugerencia para el compilador de que, si es posible alinear esta función, entonces el compilador debería considerar hacerlo. Algunas funciones se alinearán automáticamente porque son muy simples, y otras funciones que sugieren indica que no lo harán porque son complejas.

Además, me di cuenta de que está haciendo una compilación de depuración. Realmente no lo sé, pero es posible que el compilador deshabilite la creación de líneas para depurar construcciones porque dificulta las cosas para el depurador ...

0

Tuve problemas similares y encontré que solo funciona si la función en línea está escrita en un archivo de encabezado

+0

¿Por qué el voto a favor? sybreon es correcto, en el caso de que se llame a la función inlined desde otro módulo ... – bitsmack

Cuestiones relacionadas