¿Se garantiza que las funciones definidas en los encabezados estarán integradas?

StackOverflow https://stackoverflow.com/questions/2391294

  •  25-09-2019
  •  | 
  •  

Pregunta

Si defino una función que no es miembro en un encabezado, ¿el compilador siempre la incluirá o la elegirá en función de su heurística?Sé que __inline es solo una pista, ¿sucede lo mismo con las funciones en los encabezados?

¿Fue útil?

Solución

Recuerde que la inclusión de algo de una cabecera no es diferente a simplemente escribiendo directamente en el archivo de origen. Así que estar en una cabecera no hace ninguna diferencia en lo que se refiere al compilador; nunca sabía que estaba allí.

Así que cuando se define una función en un archivo de cabecera, y se incluye el archivo de encabezado en un archivo, es como que acaba de escribir la función directamente en el archivo. Así que ahora la pregunta es, "hace el compilador elegir a las cosas en línea basado en heurística?"

La respuesta es "depende del compilador". La norma no ofrece ninguna garantía sobre lo que se inline o no. Dicho esto, cualquier compilador moderna será extremadamente inteligente acerca de lo que inlines, probablemente con la heurística.

Sin embargo, llegamos a un punto interesante. Imagine que tiene una función en un encabezado y que se incluye en la cabecera de varios archivos de origen. A continuación, tendrá múltiples definiciones de la función, a través de las unidades de traducción, y esto viola la regla de una definición. Ergo, obtendrá errores de compilación. (El error de vinculador suele ser algo en la línea de: "Error, función ya definida en x y"). Lo que puede hacer es utilizar la palabra clave inline y ya no violan el ODR

Por cierto __inline no es estándar. Contrariamente a su puesto, por lo general es una extensión del compilador que fuerzas inlining, no se insinúa. inline es la palabra clave estándar, que inicialmente estaba destinado a alusión a inline. Como usted dice, los compiladores más modernos ignoran por completo en ese sentido y es hoy en día el único propósito es dar cosas enlace interno.

Otros consejos

Desde el C ++ FAQ Lite :

  

No importa cómo se designa una función   como en línea, es una petición de que el   compilador se permite ignorar: se   podría ampliar cilindros en línea algunos, todos o ninguno   de las llamadas a una función en línea.

Se elegirá basado en heurística. Asegúrese de que la declara como en línea de forma explícita lo contrario puede obtener un error de símbolo de enlace duplicado si se incluye la cabecera en más de una unidad de compilación.

Si definir una función con enlace externo en un archivo de cabecera e incluirla en más de una unidad de traducción, obtendrá error de compilación (más precisamente: enlazador erorr) por la violación de una definición regla (ODR). Así que la respuesta es "no": la definición de una función en un archivo de cabecera no será tomada por el compilador como una alusión a inlining y no le excusa de la observación de los requisitos de la ODR. No sólo esas funciones no están garantizados para ser inline, pero lo más probable es que su programa ni siquiera compilar.

Con el fin de definir una función en un archivo de cabecera y salirse con la que hay que dar, ya sea que la vinculación interna (os lo static, y terminan con la función independiente en cada unidad de traducción), o declarar explícitamente inline.

En cuanto a la heurística ... compiladores modernos normalmente considerar prácticamente cualquier función para la inclusión entre líneas (mediante la aplicación de la heurística), independientemente de donde se define y si se declara explícitamente inline o no.

No hay magia en las funciones de los encabezados.El compilador ni siquiera sabe si una función está definida en un encabezado o no.(Dado que los encabezados simplemente se copian y pegan en el archivo fuente, puede definirlos en un encabezado, pero el compilador simplemente lo ve como parte de la unidad de traducción)

También hay dos significados diferentes de "en línea" que debes tener en cuenta:

Una función puede ser en línea según lo definido por el estándar C++:Esto se hace anteponiendo a la función el inline palabra clave, o si es una función miembro, definiéndola en el lugar dentro de la definición de clase.

El efecto de esto es

  • informe al vinculador que puede encontrar la definición de función en varios archivos y que debería fusionarlos silenciosamente en lugar de generar un error.
  • facilitar que el compilador realice la inserción mejoramiento.

el en línea mejoramiento por otro lado, es simplemente el acto de reemplazar una llamada a una función por el cuerpo de la función llamada, lo que significa que esta optimización en realidad se aplica a los sitios de llamadas, no a las funciones.Una función puede llamarse normalmente en algunos lugares, pero estar integrada en otros lugares.Una llamada a función está incorporada cuando el compilador así lo desea, y es mejor separarla conceptualmente por completo del primer significado de "en línea".

El compilador aplicará la optimización incorporada si, cuando y donde lo desee.Utiliza mucha heurística para esto.Es más probable que las funciones más pequeñas estén integradas.Si determina que un sitio de llamada específico se ejecutará con suficiente frecuencia, es más probable que esté integrado.En última instancia, la heurística que utiliza se basa en "mejorará o degradará el rendimiento".Y, en general, juzga esto mejor que los seres humanos, por lo que no debería necesitar saber qué heurísticas precisas utiliza.Insertar demasiadas líneas sólo perjudicará el rendimiento.

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