Pregunta

Tengo entendido que puede usar la palabra clave en línea o simplemente poner un método en una declaración de clase a corto ctor o en un método de obtención, pero ¿el compilador toma la decisión final sobre cuándo incluir mis métodos en línea?

Por ejemplo:

inline void Foo::vLongBar()
{
   //several function calls and lines of code
}

¿El compilador ignorará mi declaración en línea si piensa que hará que mi código sea ineficiente?

Como problema adicional, si tengo un método getter declarado fuera de mi clase como este:

void Foo::bar() { std::cout << "baz"; }

¿El compilador insertará esto debajo de las cubiertas?

¿Fue útil?

Solución

El hecho de que una función esté o no en línea es, al final del día, depende completamente de el compilador Por lo general, cuanto más compleja es una función en términos de flujo, menos probable es que el compilador la incorpore. y algunas funciones, como las recursivas, simplemente no pueden estar en línea.

La razón principal para no incluir una función es que aumentaría considerablemente el tamaño general del código, lo que evitaría que Iot se mantenga en la memoria caché del procesador. De hecho, esto sería una pesimación, en lugar de una optimización.

Para dejar que el programador decida dispararse a sí mismo en el pie o en otro lugar, puede alinear la función usted mismo: escriba el código que habría ingresado en la función en el sitio de llamada de la función.

Otros consejos

Sí, la decisión final sobre si incluir o no el código en línea se encuentra en el compilador de C ++. La palabra clave en línea es una sugerencia, no un requisito.

Aquí hay algunos detalles sobre cómo se procesa esta decisión en el compilador de Microsoft C ++

Como muchos ya han publicado, la decisión final siempre depende del compilador, incluso si puede proporcionar sugerencias firmes como forceinline.
Parte del razonamiento es que la incorporación no es automática " ir más rápido " cambiar. Demasiada inline puede hacer que su código sea mucho más grande, y puede interferir con otras optimizaciones. Consulte The FAQ ++ de C ++ sobre funciones y rendimiento en línea .

Como han señalado otros, la palabra clave inline es simplemente una sugerencia al compilador para insertar el código. Dado que el compilador rutinariamente incluirá el código en línea que no ha sido marcado con inline , y no el código en línea que tiene, la palabra clave parece tan redundante como register o (antes de C ++ 0x) auto .

Sin embargo, hay otra cosa que la palabra clave inline afecta: linkage de la función de external (el valor predeterminado para funciones) a inline . El enlace en línea permite que cada unidad de compilación contenga su propia copia del código objeto, y hace que el enlazador elimine las copias redundantes del archivo ejecutable final. Si eso te recuerda a las plantillas, sí, las plantillas también usan enlaces en línea.

Sí, el compilador tiene la decisión final. En VS puede incluso integrar funciones recursivas en la profundidad especificada ;)

#pragma inline_depth( [0... 255] )

Solo para agregar mis 5 centavos ...

Encontré este artículo Gurú de la semana sobre el alineamiento muy útil.

Por lo que recuerdo, leí en alguna parte que incluso un vinculador podría integrarse, cuando vincula los archivos de objetos y encuentra que el código que se está vinculando puede estar integrado.

Saludos,
Ovanes

  

Como problema adicional, si tengo un método getter declarado fuera de mi clase como este:

void Foo::bar() { std::cout << "baz"; }
  

¿El compilador insertará esto debajo de las cubiertas?

Depende. Puede serlo para todas las personas que llaman en la misma unidad de traducción (el archivo .cpp y todas sus # definiciones incluidas). Pero todavía tiene que compilar una versión no en línea porque puede haber personas que llaman de esa función fuera de la unidad de traducción. Usted puede ver esto potencialmente en el trabajo (si su compilador puede hacerlo) a niveles de optimización altos. (En particular: compare lo que sucede cuando #incluye todos sus archivos .cpp en un .cpp en comparación con el diseño típico. Con todas las definiciones en una unidad de traducción, las oportunidades para dicha incorporación aumentan dramáticamente.)

Según mi conocimiento, el compilador hará que una función que declaraste en línea (o que escribiste dentro de una declaración de clase) no esté en línea si encuentra un bucle como para, mientras que etc. Este es un ejemplo donde el compilador tiene la última palabra en las funciones en línea.

Si realmente, positivamente, absolutamente, sin fallar NECESITA alinear el código, siempre existe la macro. C ha soportado esto durante años y como son solo un reemplazo de texto antes de la compilación, realmente, en línea, todo lo que escribes.

Es por eso que la palabra clave 'en línea' (e incluso, en algunos casos, las variantes forzadas) puede darse el lujo de no tener una forma estándar de forzarla, siempre puede escribir una macro.

Dicho esto, la palabra clave en línea suele ser mejor, porque el compilador a menudo sabe si hacer que una función en línea tenga sentido o no, y porque la línea puede interactuar con el resto de las optimizaciones del compilador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top