Acabo de enterarme de que la definición de una función C++ dentro del archivo de encabezado de una clase hace que la función esté en línea. Pero sé que poner la palabra clave en línea al lado de una función es solo una sugerencia y el compilador necesariamente no la seguirá. ¿Es esto lo mismo para las funciones de C++ definidas en el encabezado y existe una diferencia en el comportamiento entre una función de C++ independiente y una función de C++ que es parte de una clase?¿La definición de una función dentro de un encabezado siempre hace que el compilador la trate como en línea?
Respuesta
"definir una función de C++ dentro de archivo de cabecera de una clase hacen que la función en línea"
eso no es verdad. Definir una función (es decir, proporcionar el cuerpo de la función en lugar de solo una declaración) dentro de una definición de clase lo hace en línea. Por "lo hace en línea", quiero decir que es lo mismo que darle la palabra clave en línea. Pero las definiciones de clase no tienen que estar en los encabezados, y los encabezados pueden contener otras cosas además de las definiciones de clases.
Por lo tanto, en este ejemplo, la función foo
está implícitamente en línea. La función bar
no está implícita en línea:
struct Foo {
void foo() {}
void bar();
};
void Foo::bar() {}
"poner la palabra clave en línea al lado de una función es sólo una sugerencia y el compilador suele seguir necesariamente que"
inline
tiene dos efectos. Uno de ellos es una pista para el compilador que puede ignorar. El otro no es opcional, y siempre tiene su efecto. La "pista" es que se recomienda al compilador reemplazar las llamadas a esa función con una copia del código para la función en sí.
El efecto garantizado es que se puede definir una función en línea en varias unidades de traducción, y se pueden vincular entre sí, sin un error de definición múltiple, y el vinculador elimina todas menos una de las copias. Por lo tanto, si el ejemplo anterior aparece en un archivo de encabezado que se comparte entre varias unidades de traducción, el bar
debe marcarse explícitamente en línea. De lo contrario, el vinculador descubrirá múltiples definiciones de bar
, lo cual no está permitido.
A pesar del nombre, inline
en C++ se trata principalmente del segundo efecto obligatorio, no el primero, opcional. Los compiladores de optimización modernos tienen sus propias ideas sobre qué llamadas deben incluirse y no prestan mucha atención al inline
al tomar esa decisión. Por ejemplo, he visto que tiene un efecto en gcc a niveles de optimización moderados, pero a niveles bajos, casi nada está en línea, y en niveles altos, aproximadamente todo (si la definición está disponible cuando se compila la llamada) a menos que haga la función demasiado grande.
Si una función está definida en un encabezado o en un archivo cpp no tiene absolutamente ningún efecto en nada por sí mismo. Puede imaginar que lo que #include hace es copiar y pegar el archivo de encabezado en el archivo cpp en el preprocesador, antes de que el compilador lo vea. Si se define una función en la misma unidad de traducción que una llamada a ella, entonces el código de función está disponible para ser ingresado por el compilador. Si están en diferentes unidades de traducción, entonces el código no está disponible y la llamada solo puede ser ingresada por el vinculador, con optimización de todo el programa o similar. Una "unidad de traducción" significa, más o menos, "un archivo cpp, después de copiar y pegar todos los encabezados".
Los compiladores de C++ son libres de elegir lo que estará en línea y lo que no, sin importar qué pistas les dé. No debería importar si la función es parte de una clase o no, o si está en un archivo de encabezado o archivo fuente; el compilador no presta atención a esas cosas mientras toma su decisión.
Para ser precisos, el compilador no puede alinear una función para la que no tiene definición, que es el caso si la función se declara en un encabezado incluido pero definido en otra unidad de compilación. El vinculador, sin embargo, puede elegir alinear la función, si es compatible con ese tipo de optimización. –
@Carl: Es cierto, pero la pregunta era sobre la condición opuesta. Supongo que mi respuesta podría haber sido un poco más cuidadosamente redactada. –
Si coloca la definición de una función libre de plantilla en un archivo de cabecera, terminará con una definición de función en cada archivo .cpp que incluye el encabezado (directa o indirectamente). Esto puede ocasionar problemas al vincular.
Sin embargo, si declara que la función está en línea, el vinculador se asegurará de que solo use una única definición, incluso si está incluida en varios lugares.
No, no siempre. El compilador lo trata como una sugerencia, al igual que la palabra clave inline
, pero en su mayoría decide por sí solo, porque sabe mejor que usted cuáles son los costos y los beneficios. Al especificar el código, se evita la sobrecarga de llamada a la función, pero aumenta el tamaño del código, lo que tiene un impacto negativo en el rendimiento de la caché de instrucciones.
En general, el compilador generalmente ignora estas sugerencias de rendimiento del programador. Lo que no ignora (o más bien, lo que el enlazador no ignora) es que una función declarada inline
puede aparecer en varias unidades de compilación, y debe tratarse como copias múltiples de la misma función sin que se produzcan errores del enlazador.
- 1. ¿Qué hace que la consola Firebug/Chrome trate un objeto personalizado como una matriz?
- 2. Palabra clave en línea frente a la definición del encabezado
- 3. impacto en el rendimiento de la combinación "caliente" y "en línea" para una definición de función
- 4. ¿La definición de funciones en línea de C++ debe estar en el mismo archivo?
- 5. definición de macro dentro de la definición de estructura
- 6. Definición de la función dentro de otra definición de función: ¿es válida?
- 7. pure-specifier en la definición de función
- 8. Javac: trate advertencias como errores
- 9. Definición de un delegado como un puntero a función
- 10. en línea una función dentro de otra función en línea en C
- 11. en línea en la definición y declaración
- 12. Definición de variables dentro de una función Haskell
- 13. forall dentro de la definición de función recursiva
- 14. Mantener un encabezado siempre a la vista
- 15. cómo usar la constante de la clase como una definición de argumento en la función php?
- 16. Definición de clase de una línea?
- 17. hace que la condición después de && siempre se evalúe
- 18. Definición de la variable en archivos de encabezado
- 19. ¿El código en los archivos de encabezado siempre estará en línea?
- 20. ¿Cómo hacer que la carpeta de modelo ASP.Net MVC trate la fecha de entrada como UTC?
- 21. reprimir Compilador función de advertencia nunca se declaró hace referencia
- 22. Definición de una función con firma diferente
- 23. C++ - Llamar a una función dentro de una clase con el mismo nombre que la clase
- 24. ¿Dónde puedo encontrar el archivo objeto que contiene la definición de función printf?
- 25. ¿Beneficios de declarar una función como "en línea"?
- 26. Hacer que Eclipse trate el archivo .h como C++?
- 27. ¿Cómo hago que Git trate un archivo como binario?
- 28. Optimización del compilador que hace que el rendimiento se ralentice
- 29. Utilizando el tipo de definición Clojure como función parametrizada
- 30. PHP - definición de clases dentro de una función
+1 por mencionar el segundo efecto de la palabra clave 'inline'. –