Compartir a través de


inline, __inline, __forceinline

Los especificadores inline e __inline indican al compilador que inserte una copia del cuerpo de la función en cada lugar donde se llama a la función.

inline function_declarator;   
__inline function_declarator;   // Microsoft Specific
__forceinline function_declarator;   // Microsoft Specific

Comentarios

La inserción (denominada expansión alineada o alineación) solo se realiza si el análisis de costos y beneficios del compilador resulta ser rentable. La expansión alineada alivia la sobrecarga de las llamadas a función con el costo potencial de un tamaño de código mayor.

La palabra clave __forceinline invalida el análisis de costos y beneficios, y deja la decisión en manos del programador. Hay que ser prudentes al utilizar __forceinline. El uso indiscriminado de __forceinline puede dar lugar a código mayor con unas mejoras de rendimiento mínimas o, en algunos casos, incluso con pérdidas de rendimiento (debido a la mayor paginación que supone un archivo ejecutable mayor, por ejemplo).

El uso de funciones insertadas puede agilizar la ejecución del programa porque eliminan la sobrecarga asociada a las llamadas a función. Las funciones expandidas insertadas están sujetas a optimizaciones de código que no están disponibles para las funciones normales.

El compilador trata las opciones de expansión insertada y las palabras clave como sugerencias. No se garantiza que las funciones se inserten. No se puede forzar que el compilador inserte una función determinada, incluso con la palabra clave __forceinline. Al compilar con /clr, el compilador no insertará una función si se aplican atributos de seguridad a la función.

La palabra clave inline solo está disponible en C++. Las palabras clave __inline y __forceinline están disponibles tanto en C como en C++. Por compatibilidad con versiones anteriores, inline es sinónimo de __inline.

La palabra clave inline indica al compilador que se prefiere la expansión alineada. Sin embargo, el compilador puede crear una instancia independiente de la función y crear vinculaciones de llamada estándar en lugar de insertar el código. Hay dos casos en los que esto puede ocurrir:

  • Funciones recursivas.

  • Funciones a las que se hace referencia mediante un puntero en otra parte de la unidad de traducción.

Estos motivos pueden interferir con la alineación, igual que otros, a discreción del compilador; no debe depender del especificador inline para que se inserte una función.

Como ocurre con las funciones normales, no hay ningún orden definido de evaluación de los argumentos de una función insertada. De hecho, podría ser diferente del orden en que se evalúan los argumentos cuando se pasan mediante el protocolo normal de llamadas a función.

La opción /Ob de optimización del compilador ayuda a determinar si la expansión de funciones insertadas se produce realmente.

/LTCG realiza la inserción entre módulos independientemente de que se solicitara o no en el código fuente.

Ejemplo 1

// inline_keyword1.cpp
// compile with: /c
inline int max( int a , int b ) {
   if( a > b ) 
      return a;
   return b;
}

Las funciones miembro de una clase se pueden declarar alineadas mediante la palabra clave inline o colocando la definición de función dentro de la definición de clase.

Ejemplo 2

// inline_keyword2.cpp
// compile with: /EHsc /c
#include <iostream>
using namespace std;

class MyClass {
public:
   void print() { cout << i << ' '; }   // Implicitly inline
private:
   int i;
};

Específicos de Microsoft

La palabra clave __inline es equivalente a inline.

Incluso con __forceinline, el compilador no puede insertar código en todas las circunstancias. El compilador no puede insertar una función si:

  • La función o su llamador se compila con /Ob0 (la opción predeterminada para las compilaciones de depuración).

  • La función y el llamador utilizan tipos diferentes de control de excepciones (control de excepciones de C++ en uno y control de excepciones estructurado en otro).

  • La función tiene una lista de argumentos de variable.

  • La función utiliza el ensamblado insertado, a menos que se compile con /Og, /Ox, /O1 o /O2.

  • La función es recursiva y no va acompañada de la directiva #pragma inline_recursion(on). Con la directiva pragma, las funciones recursivas se alinean hasta una profundidad predeterminada de 16 llamadas. Para reducir la profundidad de inserción, utilice la directiva pragma inline_depth.

  • La función es virtual y se llama a la misma de forma virtual. Se pueden insertar llamadas directas a funciones virtuales.

  • El programa toma la dirección de la función y la llamada se realiza a través del puntero a la función. Se pueden insertar llamadas directas a funciones cuyas direcciones se han tomado.

  • La función está marcada también con el modificador naked __declspec.

Si el compilador no puede insertar una función declarada con __forceinline, genera una advertencia de nivel 1.

Se pueden sustituir las funciones recursivas insertadas hasta una profundidad especificada por la directiva pragma inline_depth, hasta un máximo de 16 llamadas. Después de dicha profundidad, las llamadas a función recursivas se tratan como llamadas a una instancia de la función. La profundidad a la que la heurística de alineación examina las funciones recursivas no puede ser superior a 16. La directiva pragma inline_recursion controla la expansión alineada de una función que se está expandiendo actualmente. Vea la opción del compilador Expansión de funciones insertadas (/Ob) para obtener información relacionada.

Específicos de Microsoft: END

Para obtener más información sobre cómo utilizar el especificador inline, vea:

Vea también

Referencia

Palabras clave de C++

noinline

auto_inline