Inlining C++ code
inline function c++ (9)
¿Hay alguna diferencia con el siguiente código?
class Foo
{
inline int SomeFunc() { return 42; }
int AnotherFunc() { return 42; }
};
¿Ambas funciones se incorporarán? ¿En línea realmente hace alguna diferencia? ¿Hay alguna regla sobre cuándo debería o no debería incluir el código en línea? A menudo uso la sintaxis de AnotherFunc
(por ejemplo, los AnotherFunc
acceso), pero raramente especifico inline
directamente.
Ambas formas deben estar delineadas exactamente de la misma manera. Inline está implícito para cuerpos de funciones definidos en una definición de clase.
El gurú de la semana # 33 de Sutter responde algunas de sus preguntas y más.
He encontrado que algunos compiladores de C ++ (Ie SunStudio) se quejan si se omite el en línea como en
int AnotherFunc() { return 42; }
Así que recomendaría usar siempre la palabra clave en línea en este caso. Y no se olvide de eliminar la palabra clave en línea si luego implementa el método como una llamada a función real, esto realmente arruinará los enlaces (en SunStudio 11 y 12 y Borland C ++ Builder). Sugeriría hacer un uso mínimo del código en línea porque al pasar por el código con un depurador, ''entrará'' en el código en línea incluso cuando se usa el comando ''paso sobre'', esto puede ser bastante molesto.
Inline es una pista del compilador y no obliga al compilador a alinear el código (al menos en C ++). Entonces, la respuesta corta es su compilador y probablemente depende del contexto, lo que sucederá en su ejemplo. La mayoría de los buenos compiladores probablemente alinearían ambos, especialmente debido a la obvia optimización de un retorno constante de ambas funciones.
En general, en línea no es algo de lo que deba preocuparse. Ofrece el beneficio de rendimiento de no tener que ejecutar instrucciones de máquina para generar un marco de pila y un flujo de control de retorno. Pero en todos los casos, excepto en los más especializados, diría que es trivial.
Inline es importante en dos casos. Uno si te encuentras en un entorno en tiempo real y no respondes lo suficientemente rápido. Dos es si el perfil del código mostraba un cuello de botella significativo en un bucle muy ajustado (es decir, una subrutina llamada una y otra vez), entonces la alineación podría ayudar.
Las aplicaciones y arquitecturas específicas también pueden llevarlo a la creación como optimización.
La palabra clave en inline
es esencialmente una pista para el compilador. El uso de inline
no garantiza que su función esté en línea, y tampoco omite garantizar que no lo hará . Simplemente le está haciendo saber al compilador que podría ser una buena idea esforzarse más para alinear esa función en particular.
VC ++ admite las directivas __forceinline y __declspec (noinline) si cree que sabe mejor que el compilador. Sugerencia: ¡probablemente no!
class Foo
{
inline int SomeFunc() { return 42; }
int AnotherFunc() { return 42; }
};
Es correcto que ambas formas garanticen compilar lo mismo. Sin embargo, es preferible no hacer ninguna de estas formas. De acuerdo con las preguntas frecuentes de C ++ , debe declararlo normalmente dentro de la definición de clase, y luego definirlo fuera de la definición de la clase, dentro del encabezado, con la palabra clave explícita en línea . Como se describe en las preguntas frecuentes, esto se debe a que desea separar la declaración y la definición de la legibilidad de los demás (la declaración es equivalente a "qué" y la definición "cómo").
¿En línea realmente hace alguna diferencia?
Sí, si el compilador concede la solicitud en línea, es muy diferente. Piense en el código en línea como una macro. En todas partes se llama, la llamada a la función se reemplaza con el código real en la definición de la función. Esto puede ocasionar la saturación del código si incorpora funciones grandes, pero el compilador generalmente lo protege al no otorgar una solicitud en línea si la función es demasiado grande.
¿Hay alguna regla sobre cuándo debería o no debería incluir el código en línea?
No conozco ninguna regla dura + rápida, pero una directriz es solo código en línea si se llama con frecuencia y es relativamente pequeña. Setters y getters son comúnmente inline. Si se trata de un área del código especialmente intensiva en el rendimiento, se debe considerar el uso de líneas internas. Recuerde siempre que está intercambiando la velocidad de ejecución para el tamaño ejecutable con la alineación.
También para agregar a lo que dijo Greg, al realizar la optimización de preformación (es decir, inline
-ing), el compilador consulta no solo las palabras clave en el código sino también otros argumentos de línea de comando para especificar cómo el compilador debería optimizar el código.
Tenga en cuenta que fuera de una clase, inline
hace algo más útil en el código: forzando (bueno, más o menos) el compilador de C ++ para generar el código en línea en cada llamada a la función, evita múltiples definiciones del mismo símbolo (la función firma) en diferentes unidades de traducción.
Por lo tanto, si inserta una función no miembro en un archivo de encabezado e incluye eso en varios archivos cpp, no tiene el enlazador gritándole. Si la función es demasiado grande para que sugiera alineación, hágalo de la manera C: declare en encabezado, defina en cpp.
Esto tiene poco que ver con si el código está realmente subrayado: permite el estilo de implementación en el encabezado, como es común para las funciones de miembro cortas.
(Imagino que el compilador será inteligente si necesita una representación no en línea de la función, como lo es para las funciones de plantilla, pero ...)