2011-05-11 13 views
57

¿por qué debería hacer algo como esto:C++ función en línea?

inline double square (double x) { return x*x;} 

en lugar de

double square (double x) { return x*x;} 

¿Hay alguna diferencia?

+0

posible duplicado de [funciones en línea vs preprocesador macros] (http://stackoverflow.com/questions/1137575/inline-functions-vs-preprocessor-macros) –

+0

en realidad hay una gran cantidad de duplicados y casi-dupes: http://stackoverflow.com/search?q=c%2B%2B+inline. Algunas de las respuestas son mejores que otras, algunas de ellas afirman falsamente que la palabra clave 'inline' hace que la función esté en línea en todos los sitios de llamadas, y así sucesivamente. Ese puede no ser el más inoportuno. –

Respuesta

73

El primero (usando inline) le permite poner esa función en un archivo de encabezado, donde se puede incluir en varios archivos de origen. El uso de inline hace que el identificador en el alcance del archivo, es muy similar a declararlo static. Sin usar inline, obtendría un error de definición de símbolo múltiple del vinculador.

Por supuesto, esto se suma a la sugerencia para el compilador de que la función debe compilarse en línea en donde se usa (evitando una sobrecarga de llamada de función). El compilador no está obligado a actuar según la sugerencia inline.

+1

Pensé que el propósito de inline es que el compilador 'expanda' el contenido de la función a la que se llama, de modo que no habrá una búsqueda vtable (o la instrucción saltará a la función en el nivel de la CPU). –

+0

¿Su primer punto es un efecto secundario [útil] de la finalidad prevista? –

+0

@Ian Fleeton: De hecho, es un efecto secundario; si un identificador en línea no tiene alcance de archivo, entonces sería imposible poner una definición de función en línea en un archivo de encabezado en absoluto. –

20

En un compilador moderno es probable que no haya mucha diferencia. Puede estar en línea sin el inline y puede no estar en línea con el inline.

+0

Tiene sentido, pasé de la experiencia de referencia y de 10 años de edad. –

27

Sí, hay una diferencia. https://isocpp.org/wiki/faq/inline-functions.

Cuando especifica que una función está en línea, hace que el compilador coloque el código del método donde sea que se llame.

void myfunc() { 
    square(2); 
} 

es idéntica a

void myfunc() { 
    2 * 2; 
} 

Llamar a una función que es bueno para la claridad del código, pero cuando esa función se llama el estado local tiene que ser empujada a la pila, un nuevo estado local está configurado para el método, y cuando está hecho, el estado anterior debe aparecer. Eso es un montón de sobrecarga.

Ahora, si sube su nivel de optimización, el compilador tomará decisiones como bucles de desenrollado o funciones de alineación. El compilador aún puede ignorar la instrucción en línea.

+2

Creo que con gcc puede usar el indicador de compilación '-Winline' para advertir cuando una función no estará en línea. Y podrías combinar eso con '-Werror' si eres un masajista. – patmanpato

2

La función en línea, si el compilador cumple, incluirá la función en línea en el código en el que se llamó como si no se llamara (como si hubiera puesto la lógica en la función de llamada) y evitará la llamada de función gastos generales.

+6

El compilador no tiene que alinear la función si no quiere, incluso si se especifica la palabra clave en línea. – Marlon

+1

@Alex Marlon no dijo que el compilador ** no ** alinearía la función, simplemente que ** no tiene que **. Esas son cosas muy diferentes. – anthropomorphic

2

inline funciona bien con el concepto de abstracción de procedimientos:

inline double square (double x) { return x*x;} 

int squareTwice(double x) { 
    double first = square(x); 
    double second = square(x); 
    return first * second; 
} 

Lo anterior es fundamentalmente similar a la siguiente:

int squareTwice(double x) { 
    double first = x*x; 
    double second = x*x; 
    return first * second; 
} 

Esto sucede porque cuando el compilador cilindros en línea se expande una función llamada, el código de la función se inserta en el flujo de código de la persona que llama; por lo tanto, puede ser más fácil resumir procedimentalmente el segundo ejemplo al primer ejemplo.

La abstracción de procedimientos permite dividir una rutina en subrutinas más pequeñas que son mucho más fáciles de leer (aunque esto puede ser una opción de estilo).

5

De Wikipedia: función en línea es una función sobre la cual se le ha solicitado al compilador que realice la expansión en línea. En otras palabras, el programador ha solicitado que el compilador inserte el cuerpo completo de la función en cada lugar al que se llame la función, en lugar de generar código para llamar a la función en el lugar donde está definida. Los compiladores no están obligados a respetar esta solicitud.

http://en.wikipedia.org/wiki/Inline_function