online definicion c++ inline-functions

c++ - definicion - inline function c



Funciones en lĂ­nea en C++ (7)

De hecho, está en línea, pero el compilador puede ignorar cualquier solicitud en línea.

Si definimos una función miembro dentro de la propia definición de clase, ¿se trata necesariamente en línea o es solo una solicitud al compilador que puede ignorar?


El compilador lo trata necesariamente como una solicitud de línea, que puede ignorar. Hay algunos modismos para definir algunas funciones en el encabezado (p . Ej., Destructores virtuales vacíos) y algunas definiciones de encabezado necesarias (funciones de plantilla), pero aparte de eso, consulte GotW # 33 para obtener más información.

Algunos han notado que el compilador puede incluso funciones en línea que nunca se lo pidió, pero no estoy seguro de si eso anularía el propósito de solicitar una función en línea.


Es una solicitud al compilador que puede ignorar.


Hay dos cosas que no deben ser agrupadas:

  1. Cómo marcar una función como en línea: defínala con la línea en frente de la firma o defínala en el punto de declaración;
  2. Lo que tratará el compilador de dicho marcado en línea: independientemente de cómo haya marcado la función como en línea, el compilador lo tratará como una solicitud.

La norma ISO C ++ 2003 dice

7.1.2 / 2 Una declaración de función (8.3.5, 9.3, 11.4) con un especificador en línea declara una función en línea. El especificador en línea indica a la implementación que la sustitución en línea del cuerpo de la función en el punto de llamada debe preferirse a la llamada a la función habitual
mecanismo. No se requiere una implementación para realizar este inline
sustitución en el punto de llamada; Sin embargo, incluso si esta en línea
se omite la sustitución, las demás reglas para las funciones en línea definidas en 7.1.2 se seguirán respetando.

7.1.2 / 3 Una función definida dentro de una definición de clase es una línea
función. El especificador en línea no aparecerá en una declaración de función de alcance de bloque.

7.1.2 / 4 Una función en línea se definirá en cada unidad de traducción en
que se utiliza y tendrá 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 su definición aparece 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 tendrá la misma dirección en todas las unidades de traducción. Una variable local estática en una línea externa
La función siempre se refiere al mismo objeto. Una cadena literal en una
La función externa en línea es el mismo objeto en una traducción diferente
unidades.


Según lo indicado por otros, un método definido dentro de una clase se solicita automáticamente en línea. Es útil entender por qué.

Supongamos que no lo fuera. Tendría que generar código para tal función, y dondequiera que se llame, una instrucción de salto a subrutina tendría que hacer referencia a la ubicación, a través del vinculador.

class A { public: void f() { ... your code ... } };

Cada vez que se ve este código, si no está en línea, el compilador solo puede asumir que debe generarse, por lo que generaría un símbolo. Supongamos que era así:

A__f_v:

Si ese símbolo fuera global, entonces si incluyera este código de clase varias veces en diferentes módulos, tendría un error de símbolo definido en forma múltiple en el momento del enlace. Entonces no puede ser global. En cambio, es archivo local.

Imagine que incluye el archivo de encabezado anterior en una serie de módulos. En cada uno, va a generar una copia local de ese código. Lo que es mejor que no compilar en absoluto, pero está obteniendo varias copias del código cuando en realidad solo necesita una.

Esto lleva a la siguiente conclusión: si su compilador no va a alinear una función, es mucho mejor declararlo en algún lugar una vez, y no solicitar que esté en línea.

Desafortunadamente, lo que está y no está en línea no es portátil. Está definido por el escritor compilador. Una buena regla general es hacer siempre cada una de las líneas, particularmente todas las funciones que solo llaman una función, en línea, a medida que se eliminan los gastos generales. Cualquier cosa por debajo de tres líneas de código lineal es casi seguro que está bien. Pero si tiene un bucle en el código, la pregunta es si el compilador lo permitirá en línea, y más concretamente, cuánto beneficio vería incluso si hiciera lo que quiere.

Considere este código en línea:

inline int add(int a, int b) { return a + b; }

No solo es casi tan pequeño como el prototipo en el código fuente, sino que el lenguaje ensamblador generado por el código en línea es más pequeño de lo que sería la llamada a una rutina. Así que este código es más pequeño, y más rápido.

Y si pasas en constantes:

int c= add(5,4);

Se resuelve en tiempo de compilación y no hay código.

En gcc, recientemente me di cuenta de que incluso si no tengo el código en línea, si es local a un archivo, de todos modos lo incluirán de forma furtiva. Solo si declaro la función en un módulo fuente separado, no se optimizará la llamada.

En el otro extremo del espectro, suponga que solicita en línea en un código de 1000 líneas. Incluso si su compilador es lo suficientemente tonto para acompañarlo, lo único que guarda es la llamada en sí, y el costo es que cada vez que lo llama, el compilador debe pegar todo ese código. Si llama ese código n veces , tu código crece por el tamaño de la rutina * n. Por lo tanto, cualquier cosa más grande que 10 líneas no vale la pena incluirla, excepto en el caso especial en el que solo se llama un número muy pequeño de veces. Un ejemplo de esto podría estar en un método privado llamado solo por otros 2.

Si solicita en línea un método que contiene un bucle, solo tiene sentido si a menudo se ejecuta un pequeño número de veces. Pero considere un bucle que itera un millón de veces. Incluso si el código está en línea, el porcentaje de tiempo empleado en la llamada es pequeño. Entonces, si tiene métodos con bucles, que tienden a ser más grandes de todos modos, vale la pena eliminarlos del archivo de encabezado porque a) el compilador tenderá a rechazarlos como en línea yb) incluso si estuvieran en línea, generalmente son no va a proporcionar ningún beneficio


Sí, las funciones que están definidas dentro de un cuerpo de clase están implícitamente en inline .

(Al igual que con otras funciones declaradas en inline , no significa que el compilador tenga que realizar una expansión en línea en los lugares donde se llama a la función, solo habilita las relajaciones permitidas de la "regla de una definición", combinado con el requisito de que una definición debe ser incluido en todas las unidades de traducción donde se utiliza la función.)