GCC y encabezados precompilados

Resuelto Mihai Todor asked hace 12 años • 1 respuestas

Después de leer este bonito artículo (El cuidado y alimentación de los encabezados precompilados), tengo algunas dudas sobre cómo pueden funcionar en la vida real. Más específicamente, ¿cómo puedo saber que necesito activar la reconstrucción del encabezado precompilado en los siguientes escenarios?

  • Decido #definealgo en uno de mis archivos .cpp que altera la forma en que el preprocesador interpreta algunos encabezados que ya están incluidos en mi encabezado precompilado.
  • Incluyo otro encabezado en uno de mis archivos .cpp que #definees una directiva de preprocesador específica que altera la forma en que el preprocesador interpreta un encabezado ya incluido en el encabezado precompilado.
  • Peor aún, el problema anterior puede ocurrir de forma recursiva, cuando ciertos encabezados #includeotros encabezados

¿El uso de encabezados precompilados debería imponer un cierto estilo de codificación restrictivo, como limitar el número de encabezados incluidos en los archivos .cpp a uno y nunca #defineincluir elementos en un archivo .cpp?

Si bien el compilador de Microsoft probablemente hace un trabajo decente con encabezados precompilados (aplicando algo de vudú específico de MS) porque, hasta donde yo sé, proporciona las opciones /Ycy /Yuque se supone hacen toda la plomería, para GCC parece que esto La funcionalidad requiere mucho trabajo manual y creatividad en Makefile y no pude encontrar una plantilla que se supone solucione todos los problemas del uso de encabezados precompilados.

Por ejemplo, si tengo un proyecto que construye varias bibliotecas, para no reconstruirlas todas después de cada cambio, tengo que usar algunos sedtrucos realmente lindos en el Makefile para detectar si uno de los encabezados #includede la biblioteca actual fue modificado. (o es #includeun encabezado modificado). Me temo siquiera pensar en las complicaciones que implicarían los encabezados prediseñados para que el script de compilación los reconstruya cada vez que sea necesario.

Mihai Todor avatar Sep 15 '12 20:09 Mihai Todor
Aceptado

El GCC actual (es decir, 4.7) y sus versiones anteriores funcionan bien con encabezados precompilados solo cuando tiene un único encabezado común para su aplicación, y cuando ese único encabezado (que incluye a su vez todos los del sistema y los específicos de la biblioteca, es necesario). por la aplicación) es #include-d (como el primer lexema sin comentarios de sus fuentes) por cada fuente de su aplicación.

Por lo tanto, debe tener un único yourapp.h archivo fuente y todos los archivos fuente (es decir, cada unidad de compilación) comenzando yourapp con las #include "yourapp.h"mismas opciones de preprocesamiento (es decir, -Do -Io -U) en la línea de comando. Ese youapp.harchivo de encabezado generalmente #includeincluye muchos otros, por ejemplo, encabezados del sistema (o GTK o Qt) como <stdlib.h>o <sys/poll.h>o [en C++] <algorithm>o <gtk/gtk.h>o <QtGui>etc.

Recuerda que -Hes una opción útil para que gccte digan qué incluye.

Es posible que sus archivos fuente tengan algunos #include archivos posteriores #include "yourapp.h" adicionales si así lo desea.

Después de que GCC haya incluido un [único] encabezado precompilado, puede, por supuesto, #definemacros, #includealgunos encabezados no precompilados, realizar una compilación condicional con #ifdef, etc. ¡Pero ese preprocesamiento no será "precompilado"!

Es posible que esto no se ajuste a sus necesidades o hábitos.

Algunas personas (especialmente de Google, en particular Diego Novillo) están trabajando en la rama PreParsed Header (pph) para mejorar la situación, pero la troncal GCC actual aún no ha conseguido ese trabajo.

La explicación sobre ese comportamiento de GCC es que un encabezado preprocesado es esencialmente un punto de control serializado persistente de todo el montón de GCC (relacionado con la administración de memoria dentro de GCC a través de Ggc y GTY y gengtype). Ese montón con puntos de control se puede cargar solo cuando gccestá en su estado vacío inicial. Tan pronto como se sabe algo gcc(en realidad cc1o cc1plus), ya no puede cargar ningún archivo de encabezado precompilado *.h.gchy volverá a analizar el archivo de encabezado textual *.h.


adendas (noviembre de 2014 y posteriores)

Incluso GCC 4.9 quiere un único encabezado precompilado. El esfuerzo de encabezado previamente analizado por Diego Novillo et al. ha sido abandonado.

Las versiones futuras (posteriores a C++ 14 ) del estándar C++ podrían definir un mecanismo de módulo. Véase, por ejemplo, la propuesta n4047 y el estándar C++20 .

(Apéndices adicionales, verano de 2020) Esto sigue siendo válido para GCC-10 , donde existen varias opciones de analizadores estáticos . Véase también el analizador estático de Clang y este borrador del informe. Considere usar Frama-C .

Basile Starynkevitch avatar Sep 15 '2012 14:09 Basile Starynkevitch