c++ - ejecutar - programas para compilar
¿Cuándo compilan los compiladores el código en C++? (11)
El compilador optimiza como él quiere, a menos que especifique lo contrario.
En C ++, ¿los métodos solo se ingresan si se declaran explícitamente en inline
(o se definen en un archivo de encabezado), o si los compiladores tienen acceso a los métodos en línea como mejor les parezca?
El compilador puede alinear lo que quiera en caso de que la alineación no viole la semántica del código y pueda alcanzar el código de la función. También puede alinear de forma selectiva: realice una línea cuando considere que es una buena idea y no en línea cuando no sienta que es una buena idea o cuando viole la semántica del código.
Algunos compiladores pueden hacer la creación incluso si la función está en otra unidad de traducción, que se denomina generación de código de tiempo de enlace.
Los casos típicos de cuando la línea entrante violaría la semántica del código son llamadas virtuales y pasar una dirección de función a otra función o almacenarla.
La palabra clave en línea realmente solo le dice al vinculador (o le dice al compilador que le diga al vinculador) que múltiples definiciones idénticas de la misma función no son un error. Lo necesitará si desea definir una función en un encabezado, o obtendrá errores de "definición múltiple" del vinculador, si el encabezado está incluido en más de una unidad de compilación.
El motivo por el que se elige en línea como palabra clave parece ser que la única razón por la que uno querría definir una función (no plantilla) en un encabezado es para que el compilador pueda insertarla. El compilador no puede alinear una llamada de función, a menos que tenga la definición completa. Si la función no está definida en el encabezado, el compilador solo tiene la declaración y no puede alinear la función aunque lo desee.
Hoy en día, he escuchado que no solo el compilador optimiza el código, sino que el enlazador puede hacerlo también. Un enlazador podría (si no lo hacen ya) llamar a la función en línea incluso si la función no se definió en la misma unidad de compilación.
Y probablemente no sea una buena idea definir funciones más grandes que quizás una sola línea en el encabezado, si es que lo está (mal para el tiempo de compilación, y si la función grande estuviera en línea, podría llevar a la saturación y un peor rendimiento).
La palabra clave en línea es solo una solicitud al compilador. El compilador se reserva el derecho de realizar o no una función en línea. Uno de los principales factores que impulsa la decisión del compilador es la simplicidad del código (no muchos bucles)
Las funciones de miembro se declaran en línea por defecto. (El compilador también decide aquí)
Estas no son reglas duras y rápidas. Varía según las implementaciones del compilador.
Si alguien conoce otros factores involucrados, por favor publique.
Los compiladores pueden ignorar su declaración en línea. Es básicamente utilizado por el compilador como una pista para decidir si lo hace o no. Los compiladores no están obligados a alinear algo que está marcado en línea, o no alinear algo que no está en línea. Básicamente, estás a merced de tu compilador y del nivel de optimización que elijas.
Sí, el compilador puede codificar en línea incluso si no está explícitamente declarado como en inline
.
Básicamente, siempre que la semántica no se modifique, el compilador puede prácticamente hacer lo que quiera con el código generado. El estándar no obliga a nada especial en el código generado.
Si no me equivoco, cuando las optimizaciones están activadas, el compilador alineará cualquier rutina o método adecuado.
Texto del Centro de información de IBM ,
El uso del especificador en línea es solo una sugerencia para el compilador de que se puede realizar una expansión en línea; el compilador puede ignorar la sugerencia.
C Idioma Cualquier función, con la excepción de main, se puede declarar o definir como en línea con el especificador de función en línea. Las variables locales estáticas no se pueden definir dentro del cuerpo de una función en línea.
Las funciones C ++ implementadas dentro de una declaración de clase se definen automáticamente en línea. Las funciones regulares de C ++ y las funciones miembro declaradas fuera de una declaración de clase, a excepción de main, se pueden declarar o definir como en línea con el especificador de función en línea. Locales estáticos y literales de cadena definidos dentro del cuerpo de una función en línea se tratan como el mismo objeto en las unidades de traducción;
Los compiladores pueden alinear cualquier función o no alinearla. Se les permite usar la decoración en inline
como una pista para esta decisión, pero también se les permite ignorarla.
También tenga en cuenta que las funciones miembro de clase tienen una decoración en inline
implícita si se definen en la definición de clase.
Algunas de las situaciones en las que la expansión en línea NO puede funcionar son:
- Para funciones que devuelven valores, si existe un bucle, un interruptor o un goto
- Para la función que no devuelve valores, si sale una declaración;
- Si las funciones contienen variables estáticas
- Si las funciones en línea son recursivas.
La expansión en línea hace que un programa se ejecute más rápido porque se elimina la sobrecarga de una declaración de función y de devolución. Sin embargo, hace que el programa ocupe más memoria porque las instrucciones que definen las funciones en línea se reproducen en cada punto donde se llama a la función. Entonces, se necesita una compensación.
(Como figura en uno de mis libros OOP)
La documentación de tu compilador debe decirte ya que depende de la implementación. Por ejemplo, GCC de acuerdo con su manual nunca inserta ningún código a menos que se aplique optimización.
Si el compilador no inserta el código, la palabra clave en línea tendrá el mismo efecto que la estática , y cada unidad de compilación que llame al código tendrá su propia copia. Un enlazador inteligente puede reducir estos a una sola copia.