2009-04-02 8 views
7

Hasta hace un tiempo, mi base de código estaba muy cerca de #include infierno. Cada vez que cambio un archivo .h medianamente importante, prácticamente todos los archivos se vuelven a compilar.
La razón principal de tal alta dependencia del encabezado es que tengo muchas funciones pequeñas que deben estar en línea y tuve la impresión de que para trabajar en línea necesitan estar en la misma unidad de traducción que el código de llamada, por lo que necesitan estar en el encabezado Para la función en línea incluso para compilar otros encabezados deben incluirse también en el encabezado, ad infimum.C++: funciones en línea y generación de código de tiempo de enlace

Ingrese link-time code generation (en Visual Studio). Una de las principales ventajas declaradas de esto es que ahora la función en línea puede cruzar unidades de traducción.
Pero todavía soy dudoso. ¿Cómo puedo estar realmente seguro de que estas funciones realmente estén incluidas? Me doy cuenta de que el compilador básicamente puede hacer lo que quiera sin importar dónde defina la función.

¿Hay alguna manera de verificar qué se incluye?

+0

¿Por qué es tan esencial que estas funciones estén en línea? Eso parece extraño. Por lo general, desea que las funciones estén en línea * cuando benefician el rendimiento *, que el compilador normalmente puede determinar mejor que usted – jalf

+0

@ Rüdiger Stevens - En realidad, es posible. Consulte la opción ': PGINSTRUMENT' de VC++ en el indicador/LTCG. http://msdn.microsoft.com/en-us/library/xbf3tbeh%28VS.80%29.aspx –

Respuesta

1

Una vez que tenga el ejecutable, puede usar herramientas para inspeccionarlo y buscar los nombres de las funciones en línea en las tablas de símbolos. Una de esas herramientas que es muy útil es Dependency Walker.

Esto, por supuesto, asume que puede obtener una compilación que combine ambas configuraciones de optimización suficientes para que el compilador se moleste con la alineación, conservando los símbolos.

Para Visual Studio, creo que las versiones "Release" a menudo coinciden con esas, pero no estoy del todo seguro.

+1

Mantener símbolos no es un problema con la información de depuración y optimizaciones activadas, pero una función puede estar en línea en un lugar, y no en el otro –

+0

Dependency walker solo lista las funciones exportadas e importadas.Asumiendo que tengo símbolos, ¿cómo puedo obtener una lista textual? – shoosh

+0

Oops, mi mal, no me había dado cuenta. Tal vez este puerto de la herramienta Unix 'nm' haga el truco: . – unwind

3

Seguramente no le importa si las cosas se incorporan, solo le importa si el rendimiento es satifactorio. Pero si realmente quiere averiguarlo, examine el código que genera el compilador. Puede hacer esto más fácilmente a través del depurador, usando una ventana de vista de ensamblador.

3

Nunca puede estar seguro de que las funciones estén en línea. Depende del compilador elegir eso. Pero puede hacer que sea más fácil para el compilador al permitirle encontrar el código objeto asociado con la función.

Aquí es donde entra la generación de código de tiempo de enlace. Los compiladores ya no generan código de objeto, generan una forma de lenguaje intermedio y es el vinculador el que realmente compila el código.

Para comprobar lo que se incorpora, me temo que le queda la generación de salida de ensamblaje junto con su código objeto. Eso le permite leer el código de objeto exacto producido cuando se invoca una determinada función y quedará muy claro si hay una "llamada" allí o no.

3

Una forma relativamente fácil es utilizar un generador de perfiles. Si una función está en línea, no la verá en el flujo del gráfico de control.

7

Sé que es un tabú en C++ decir esto, pero podría implementar las funciones como macros de preprocesador. Discúlpenme mientras voy a lavarme la boca con jabón.

+0

+1: Porque a veces es la última oportunidad para decirle al compilador que "alinee" tu función si insiste en no incluirla, incluso si sabes que el rendimiento sería mejor :-) – mmmmmmmm

Cuestiones relacionadas