significado programacion librerias funciones ejemplos codigos cabecera archivos c++ inline-functions

programacion - librerias de c++



¿Qué significa que una función de C++ esté en línea? (9)

Ver título: ¿qué significa para una función de C ++ estar en línea?


@Anciano

Los compiladores solo se alinean en línea sin marcar como funciones en línea SOLAMENTE si así lo solicita.

Solo si por "solicitud" quiere decir "activar optimizaciones".

Es correcto solo en los casos en la casusa.

Es correcto en ambos.

Inline no genera ninguna información adicional que el enlazador pueda usar. Compiel 2 archivos de objeto y verificación. ¡Permite múltiples definiciones exactas porque los símbolos no se exportan! ¡No porque ese sea su objetivo!

¿Qué quiere decir con "los símbolos no se exportan"? las funciones en línea no son estáticas. Sus nombres son visibles; ellos tienen un enlace externo. Para citar del Estándar C ++:

void h (); vacío en línea h (); // enlace externo

vacío en línea l (); vacío l (); // enlace externo

Lo de las definiciones múltiples es en gran medida el objetivo. Es obligatorio:

Se debe definir una función en línea en cada unidad de traducción en la que se utiliza y debe tener exactamente la misma definición en cada caso (3.2). [Nota: se puede encontrar una llamada a la función en línea antes de que su definición aparezca en la unidad de traducción. ] Si una función con enlace externo se declara en línea en una unidad de traducción, se declarará en línea en todas las unidades de traducción en las que aparece; no se requiere diagnóstico. Una función en línea con enlace externo debe tener la misma dirección en todas las unidades de traducción.


De manera informal, significa que los compiladores pueden injertar los contenidos de la función en el sitio de llamadas, de modo que no haya una llamada de función. Si su función tiene grandes instrucciones de control (por ejemplo, if , switch , etc.) y las condiciones se pueden evaluar en el momento de la compilación en el sitio de llamadas (por ejemplo, valores constantes utilizados en el sitio de llamadas), su código termina mucho más pequeño ( las ramas no utilizadas se dejan caer).

Más formalmente, las funciones en línea también tienen un vínculo diferente. Dejaré que los expertos en C ++ hablen sobre ese aspecto.


El compilador puede insertar una función que marca como en línea. No hay garantía de que el compilador lo haga. El compilador usa semántica compleja en el dispositivo cuando lo hace o no.

Cuando el compilador decide que una función debe estar en línea, la llamada a la función, en el código de la persona que llama, se reemplaza por el código de la llamada. Esto significa que guarda las operaciones de la pila, la misma llamada y mejora la ubicación de la memoria caché del código. A veces eso puede conducir a grandes ganancias de rendimiento. Especialmente en funciones de acceso a datos de 1 línea, como los accesos utilizados en código orientado a objetos.

El costo suele ser el resultado de un código más grande, lo que podría perjudicar el rendimiento. Esta es la razón por la que establecer una función en línea es solo una "bandera verde" para el compilador, que no necesita seguir. El compilador intentará hacer lo mejor.

Como regla general para principiantes que no quieren lidiar con peculiaridades de vinculación. la función en línea debe ser llamada por otra función en las mismas unidades de compilación. Si desea implementar una función en línea que se pueda usar en varias unidades de compilación, conviértalo en un archivo de encabezado declarado e implementado en línea.

¿Por qué?

Ejemplo: en el archivo de cabecera inlinetest.h

int foo(); inline int bar();

En la unidad de compilación inlinetest.cpp

int foo(){ int r = bar(); return r; } inline int bar(){ return 5;};

Luego, en main.cpp

#include "inlinetest.h" int main() { foo(); //bar(); }

Compila un archivo de objeto a la vez. Si elimina el comentario de esa llamada de "barra", tendrá un error. Porque la función en línea solo se implementa en el archivo de objeto inlinetest.o y no se exporta. Al mismo tiempo, la función foo, muy probablemente haya incrustado en ella el código de la función de la barra (ya que la barra es una sola línea sin operación de E / S, entonces es muy probable que esté en línea)

Pero si en el archivo de encabezado había declarado la función en línea y la implementó en línea, entonces podría usarla en cualquier unidad de compilación que incluya ese encabezado. ("muestra de código");

Elimine la palabra clave en línea y el compilador NO causará el error incluso con la llamada de barra en main. Y no se realizará inline a menos que solicite al compilador que incorpore todas las funciones. Ese no es un comportamiento estándar en la mayoría de los compiladores.


El cuerpo de la función se inserta literalmente dentro de la función de llamada. Por lo tanto, si tiene varias llamadas a esta función, obtiene múltiples copias del código. El beneficio es que obtiene una ejecución más rápida.

Por lo general, las funciones muy cortas están en línea, cuando la copia del cuerpo de la función no sería mucho mayor que el código de prólogo / epílogo habitual generado para la llamada a función normal.

Puede leer más en el artículo de MSDN sobre inline - http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx


Las funciones en línea alteran el perfil de rendimiento de su aplicación generando instrucciones que se colocan en el segmento de código de su aplicación. Si una función está en línea es a discreción de su compilador. En mi experiencia, la mayoría de los compiladores modernos son buenos para determinar cuándo cumplir con la solicitud de un usuario de estar en línea.

En muchos casos, al establecer una función mejorará su rendimiento. Hay una sobrecarga inherente a las llamadas de función. Sin embargo, hay razones por las que incluir una función puede ser negativo:

  • Aumentar el tamaño del ejecutable binario mediante la duplicación de código podría ocasionar un problema en el disco, ralentizando la aplicación.
  • El código de entrada podría contribuir a errores de caché, o posiblemente contribuir a los hits de caché dependiendo de su arquitectura.

Las preguntas frecuentes de C ++ hacen un buen trabajo al explicar las complejidades de la palabra clave: http://www.parashift.com/c++faq-lite/inline-functions.html#faq-9.3


Llamar a una función impone una cierta penalización de rendimiento para la CPU por el simple hecho de tener una secuencia lineal de instrucciones. Los registros de la CPU deben escribirse en otra ubicación, etc. Obviamente, los beneficios de tener funciones generalmente superan la penalización de rendimiento. Pero, donde el rendimiento será un problema, por ejemplo, la legendaria función de "bucle interno" o algún otro cuello de botella, el compilador puede insertar el código de máquina para la función en el flujo principal de ejecución en lugar de pasar por el impuesto de la CPU para llamar a una función .


Significa una cosa y una sola cosa: que el compilador eliminará múltiples definiciones de la función.

Normalmente, una función no se puede definir varias veces (es decir, si coloca una definición de función no en línea en un encabezado y luego #include en múltiples unidades de compilación, recibirá un error de enlazador). Marcar la definición de función como "en línea" suprime este error (el enlazador asegura que ocurre lo correcto).

¡NO SIGNIFICA NADA MÁS!

Más significativamente, NO significa que el compilador incorporará la función compilada en cada sitio de llamadas. Si eso ocurre depende totalmente de los caprichos del compilador, y generalmente el modificador en línea hace poco o nada para cambiar la mente del compilador. El compilador puede, y lo hace, alinear funciones que no están marcadas en línea, y puede realizar llamadas a funciones que están marcadas en línea.

Elidir múltiples definiciones es lo que hay que recordar.


Además de las otras respuestas (perfectamente correctas) sobre las implicaciones de rendimiento de inline , en C ++ también debe tener en cuenta que esto le permite poner una función en un encabezado de manera segura:

// my_thing.h inline int do_my_thing(int a, int b) { return a + b; } // use_my_thing.cpp #include "my_thing.h" ... set_do_thing(&do_my_thing); // use_my_thing_again.cpp ... set_other_do_thing(&do_my_thing);

Esto se debe a que el compilador solo incluye el cuerpo real de la función en el primer archivo de objeto que necesita una función invocable regular para compilarse (normalmente porque se tomó su dirección, como mostré anteriormente).

Sin la palabra clave en inline , la mayoría de los compiladores darían un error sobre la definición múltiple, por ejemplo, para MSVC:

use_my_thing_again.obj : error LNK2005: "int __cdecl do_my_thing(int,int)" (?do_my_thing@@YAHHH@Z) already defined in use_my_thing.obj <...>/Scratch.exe : fatal error LNK1169: one or more multiply defined symbols found


La función se coloca en el código, en lugar de llamarse, de forma similar al uso de macros (conceptualmente)

Esto puede mejorar la velocidad (sin llamada de función), pero causa la inflamación del código (si la función se usa 100 veces, ahora tiene 100 copias)

Debe tener en cuenta que esto no obliga al compilador a realizar la función en línea, y lo ignorará si considera que es una mala idea. Del mismo modo, el compilador puede decidir hacer las funciones normales en línea para usted.

Esto también le permite colocar toda la función en un archivo de encabezado, en lugar de implementarlo en un archivo cpp (que de todos modos no puede, desde entonces obtiene un externo no resuelto si fue declarado en línea, a menos, por supuesto, que solo ese archivo cpp lo use )