El preprocesador de volcado GCC define

¿Hay alguna manera para que gcc / g ++ volque su preprocesador se defina desde la línea de comando? Me refiero a cosas como __GNUC__ , __STDC__ , y así sucesivamente.

Sí, use las opciones -E -dM lugar de -c. Ejemplo (las envía a stdout):

  gcc -dM -E - < /dev/null 

Del manual de gcc :

En lugar de la salida normal, genere una lista de directivas `#define 'para todas las macros definidas durante la ejecución del preprocesador, incluidas las macros predefinidas. Esto le proporciona una forma de averiguar qué está predefinido en su versión del preprocesador. Suponiendo que no tiene ningún archivo foo.h, el comando

 touch foo.h; cpp -dM foo.h 

mostrará todas las macros predefinidas.

Si usa -dM sin la opción -E, -dM se interpreta como un sinónimo de -fdump-rtl-mach.

Normalmente lo hago de esta manera:

 $ gcc -dM -E - < /dev/null 

Tenga en cuenta que algunas definiciones de preprocesador dependen de las opciones de línea de comando; puede probarlas agregando las opciones relevantes a la línea de comando anterior. Por ejemplo, para ver qué opciones de SSE3 / SSE4 están habilitadas de manera predeterminada:

 $ gcc -dM -E - < /dev/null | grep SSE[34] #define __SSE3__ 1 #define __SSSE3__ 1 

y luego compare esto cuando se especifique -msse4 :

 $ gcc -dM -E -msse4 - < /dev/null | grep SSE[34] #define __SSE3__ 1 #define __SSE4_1__ 1 #define __SSE4_2__ 1 #define __SSSE3__ 1 

De forma similar, puede ver qué opciones difieren entre dos conjuntos diferentes de opciones de línea de comando, por ejemplo, comparar el preprocesador define para los niveles de optimización -O0 (ninguno) y -O3 (completo):

 $ gcc -dM -E -O0 - < /dev/null > /tmp/O0.txt $ gcc -dM -E -O3 - < /dev/null > /tmp/O3.txt $ sdiff -s /tmp/O0.txt /tmp/O3.txt #define __NO_INLINE__ 1 <> #define __OPTIMIZE__ 1 

Respuesta tardía: las otras respuestas me parecieron útiles, y quería agregar un poco más.


¿Cómo descargo macros de preprocesador provenientes de un archivo de cabecera particular?

 echo "#include " | gcc -E -dM - 

En particular, quería ver en qué se definía SOMAXCONN en mi sistema. Sé que podría abrir el archivo de encabezado estándar, pero a veces tengo que buscar un poco para encontrar las ubicaciones de los archivos de encabezado. En su lugar, puedo usar este one-liner:

 $ echo "#include " | gcc -E -dM - | grep SOMAXCONN #define SOMAXCONN 128 $ 

El enfoque simple ( gcc -dM -E - < /dev/null ) funciona bien para gcc pero falla para g ++. Recientemente solicité una prueba para una función de C ++ 11 / C ++ 14. Las recomendaciones para sus nombres de macro correspondientes se publican en https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations . Pero:

 g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates 

siempre falla, porque invoca silenciosamente los controladores C (como si los invocó gcc ). Puede ver esto comparando su salida con la de gcc o agregando una opción de línea de comando específica de g ++ como (-std = c ++ 11) que emite el mensaje de error cc1: warning: command line option '-std=c++11' is valid for C++/ObjC++ but not for C

Como (gcc no C ++) nunca admitirá "Alias ​​de plantillas" (consulte http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ) debe agregar el -x c++ opción -x c++ para forzar la invocación del comstackdor C ++ (Créditos para usar las opciones -x c++ lugar de un archivo ficticio vacío ve a yuyichao, ver a continuación):

 g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates 

No habrá salida porque g ++ (la revisión 4.9.1, por defecto es -std = gnu ++ 98) no habilita las características de C ++ 11 de forma predeterminada. Para hacerlo, usa

 g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates 

que finalmente rinde

 #define __cpp_alias_templates 200704 

teniendo en cuenta que g ++ 4.9.1 no admite " -std=c++11 plantillas" cuando se invoca con -std=c++11 .

Un enfoque portátil que funciona igual de bien en Linux o Windows (donde no hay / dev / null):

 echo | gcc -dM -E - 

Para c ++ puede usar (reemplace c++11 con cualquier versión que use):

 echo | gcc -x c++ -std=c++11 -dM -E - 

Funciona al decirle a gcc que preprocesen stdin (que se produce por echo) e imprime todo el preprocesador define (busca -dletters ). Si desea saber qué se define se agregan cuando incluye un archivo de encabezado, puede usar la opción -dD que es similar a -dM pero no incluye macros predefinidas:

 echo "#include " | gcc -x c++ -std=c++11 -dD -E - 

Tenga en cuenta, sin embargo, que la entrada vacía aún produce muchas definiciones con la opción -dD .

Mientras trabajas en un proyecto grande que tiene un sistema de comstackción complejo y donde es difícil obtener (o modificar) el comando gcc / g ++ directamente, hay otra manera de ver el resultado de la expansión de macros. Simplemente redefina la macro y obtendrá resultados similares a los siguientes:

 file.h: note: this is the location of the previous definition #define MACRO current_value