GCC y encabezados precomstackdos

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

  • Decido # definir algo en uno de mis archivos .cpp que altera la forma en que el pre-procesador interpreta algunos encabezados que ya están incluidos en mi encabezado precomstackdo
  • Incluyo otro encabezado en uno de mis archivos .cpp que #define una directiva de preprocesador específica que altera la forma en que el preprocesador interpreta un encabezado ya incluido en el encabezado precomstackdo
  • Peor aún, el problema anterior puede ocurrir recursivamente, cuando ciertos encabezados #include otros encabezados

¿Debe el uso de encabezados precomstackdos imponer un cierto estilo de encoding restrictivo como limitar el número de encabezados incluidos en los archivos .cpp a uno y nunca #define definir cosas en un archivo .cpp?

Si bien el comstackdor de Microsoft probablemente hace un trabajo decente con encabezados precomstackdos (aplicando algo de vudú específico para MS) porque, hasta donde yo sé, proporciona las opciones /Yc y /Yu que se supone que deben hacer todas las cañerías, para GCC parece que esta funcionalidad requiere mucho trabajo manual y creatividad en el archivo Makefile y no pude encontrar una plantilla que supuestamente solucione todos los inconvenientes del uso de encabezados precomstackdos.

Por ejemplo, si tengo un proyecto que construye varias bibliotecas, para no reconstruir todas ellas después de cada cambio, tengo que usar algunos trucos de sed realmente lindos en el Makefile para detectar si uno de los encabezados #include d por el actual la biblioteca fue modificada (o es #include un encabezado modificado). Me temo incluso pensar en las complicaciones que implicarían los encabezados preconstruidos para que el script de comstackción los reconstruya cada vez que sea necesario.

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

Por lo tanto, debe tener un solo yourapp.h y tener cada archivo fuente (es decir, cada unidad de comstackción) de yourapp comenzando con #include "yourapp.h" con las mismas opciones de preprocesamiento (es decir, -D o -I o -U ) en el comando línea. Ese archivo de encabezado youapp.h generalmente youapp.h #include -ing muchos otros, por ejemplo, encabezados de sistema (o GTK o Qt) como o o [en C ++] o o etc.

Recuerde que -H es una opción útil para que gcc le gcc qué está incluido.

Sus archivos de origen pueden tener #include adicional después de #include "yourapp.h" si así lo desea.

Después de que GCC haya incluido un encabezado precomstackdo [único], es posible, por supuesto, #define macros, #include un encabezado no precomstackdo, hacer una comstackción condicional con #ifdef , etc. Pero ese preprocesamiento no será “precomstackdo”. !

Esto puede no ajustarse a tus necesidades o hábitos.

Algunas personas (especialmente de Google, especialmente Diego Novillo) están trabajando en la sucursal PreParsed Header (pph) para mejorar la situación, pero el tronco actual de GCC 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 punto de control solo se puede cargar cuando gcc está en su estado vacío inicial. Tan pronto como se sepa algo de gcc (en realidad cc1 o cc1plus ) ya no podrá cargar ningún archivo de encabezado precomstackdo *.h.gch y volverá a analizar el archivo de encabezado textual *.h .


adenda (noviembre de 2014)

Incluso GCC 4.9 quiere un único encabezado precomstackdo. El esfuerzo del encabezado pre-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. Ver, por ejemplo, la propuesta n4047 .

(adiciones adicionales, diciembre de 2015) Esto todavía se aplica a GCC-5 y al futuro GCC-6.