2009-07-30 9 views
9

Entiendo que puede usar la palabra clave en línea o simplemente poner un método en una declaración de clase ala short ctor o un método getter, pero ¿el compilador toma la decisión final sobre cuándo alinear mis métodos?¿El compilador decide cuándo alinear mis funciones (en C++)?

Por ejemplo:

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

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

Como una cuestión secundaria, si tengo un método getter declarado fuera de mi clase como esta:

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

¿El compilador de línea de este bajo las sábanas?

Respuesta

9

Sea o no un fiunction es inline es decir, al final del día, en su totalidad hasta el compilador. Normalmente, cuanto más compleja es una función en términos de flujo, es menos probable que el compilador lo alinee. y algunas funciones, como las recursivas, simplemente no pueden incluirse.

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

En cuanto a permitir que el programador se pegue un tiro en el pie, o en otro lugar, puede alinear la función usted mismo: escriba el código que habría estado en la función en lo que habría sido el sitio de llamada de la función.

+0

Ver mi comentario sobre la respuesta de JaredPar, por favor. – jkeys

+1

Las funciones recursivas se pueden insertar en la profundidad especificada :) – AraK

+1

¿Cómo sabe el compilador cuál será la profundidad en tiempo de compilación? –

15

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

Éstos son algunos detalles en cuanto a cómo esta decisión se procesa en Microsoft C++ Compiler

+1

¿Podrías explicar por qué es esto? Pensé que el objetivo de C++ es darle al programador suficiente cuerda para ahorcarse, pero esto parece restrictivo. ¿Hay una buena razón? – jkeys

+1

@Hooked, eche un vistazo al enlace que publiqué. Entra en detalles sobre por qué esto no siempre es bueno. El primer elemento que me viene a la mente son las funciones recursivas de la cabeza. – JaredPar

+1

El estándar establece que incluso __forceinline no finaliza el debate, el compilador todavía tiene la última palabra. Puedo entender cuando inline sería inapropiado, pero si un programador/perfilador decide anular el compilador, ¿cuáles son sus opciones? Ese enlace no detalla la razón detrás de dejar que el compilador decida. – jkeys

1

Según mi conocimiento, el compilador automáticamente hará que una función que declaró en línea (o escribió dentro de una declaración de clase) no sea en línea si encuentra un bucle como para, mientras que etc. Este es un ejemplo donde el compilador tiene la última decir en funciones en línea.

+0

Yo ... ¿tiene alguna fuente para respaldar ese reclamo? – jkeys

+0

¿Un bucle? ¿Por qué un bucle? ¿No te refieres a la recursión? –

+0

Es específico de la implementación. El estándar no dice nada sobre cuándo una función puede no estar en línea; solo esa implementación tiene la decisión final. –

4

Como muchos ya han publicado, la decisión final es siempre hasta el compilador, incluso si usted puede dar pistas firmes como forceinline.
Parte del razonamiento es que inline no es un cambio automático "ir más rápido". Demasiada inclusión puede hacer que su código sea mucho más grande y puede interferir con otras optimizaciones. Ver The C++ FAQ Lite about inline functions and performance.

+0

Gracias por el enlace. He leído la mayor parte del Faq Lite, pero no esto. – jkeys

2

Como una cuestión secundaria, si tengo un método getter declarado fuera de mi clase como esta:

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

¿El compilador de línea de este bajo las sábanas?

Depende. Puede hacerlo para todas las personas que llaman en la misma unidad de traducción (el archivo .cpp y todas sus definiciones incluidas). Pero aún 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. Puede ver esto en el trabajo (si su compilador realmente puede hacerlo) en altos niveles de optimización. (En particular: compare lo que sucede cuando #incluye todos sus archivos .cpp en un archivo .cpp vs. el diseño típico. Con todas las definiciones en una unidad de traducción, las oportunidades para tal creación aumentan drásticamente)

+0

Oh, yo no sabía eso. No sé exactamente qué hace el enlazador (me han echado a perder con mis elegantes IDE, nunca he tenido que compilar por línea de comandos y seguir el proceso). – jkeys

+0

Comprender cómo funciona el vinculador debería ser bastante transparente (no debería necesitar saberlo para realizar el trabajo). Pero termina siendo particularmente importante para aprender sobre esto en C++, porque muchos constructos de lenguaje no se comportan del modo que cabría esperar si no se sabe qué es visible para el vinculador y qué no. 'inline' es el más grande, pero la diferencia entre lo que entra en' .h' y '.cpp', lo que' static' significa, dónde pueden ir las plantillas ... surgen todas. Lamentablemente, la vinculación puede hacer que tropieces en C++ si no tienes una comprensión básica de la misma. – quark

3

Como han notado otros , la palabra clave inline es simplemente una sugerencia para que el compilador incorpore el código. Como el compilador rutinariamente incluirá el código que no se ha marcado con inline, y no el código en línea que tiene, la palabra clave parece tan redundante como register o (anterior a C++ 0x) auto.

Sin embargo, no es otra cosa que los efectos inline de palabras clave: Cambia el vinculación de la función de externa (el valor por defecto para las funciones) a en línea. La vinculación en línea permite que cada unidad de compilación contenga su propia copia del código objeto, y hace que el enlazador elimine copias redundantes del ejecutable final. Si eso te recuerda las plantillas, sí, las plantillas también usan enlaces en línea.

3

Sólo para añadir mis 5 centavos ...

me encontré con este artículo sobre Guru of Week inlining muy útil.

Por lo que recuerdo, he leído en algún lado que incluso un enlazador puede hacer una línea, cuando vincula los archivos objeto y descubre que el código que se está enlazando puede estar en línea.

Saludos,
Ovanes

1

Si realmente, positivamente, absolutamente, sin falta NECESIDAD de inline el código, siempre existe la macro. C los ha apoyado durante años y, debido a que son solo un reemplazo de texto antes de la compilación, realmente, realmente, escriben todo lo que escribes.

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

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

Cuestiones relacionadas