GCC dump preprocesador define
g++ c-preprocessor (6)
El enfoque simple ( gcc -dM -E - < /dev/null
) funciona bien para gcc pero falla para g ++. Hace poco requerí una prueba para una característica 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 fueran invocados por 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
Porque (no C ++) gcc 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 compilador de C ++ (los créditos para usar las opciones -x c++
lugar de un archivo ficticio vacío van a yuyichao, ver más abajo):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
No habrá salida porque g ++ (revisión 4.9.1, por defecto es -std = gnu ++ 98) no habilita las características de C ++ 11 de forma predeterminada. Para ello, utilice
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 admite " -std=c++11
plantillas" cuando se invoca con -std=c++11
.
¿Hay alguna forma para que gcc / g ++ descargue sus definiciones de preprocesador desde la línea de comandos? Me refiero a cosas como __GNUC__
, __STDC__
, y así sucesivamente.
Mientras se trabaja en un proyecto grande que tiene un sistema de compilación complejo y donde es difícil obtener (o modificar) el comando gcc / g ++ directamente, hay otra forma de ver el resultado de la expansión de macros. Simplemente redefina la macro y obtendrá una salida similar a la siguiente:
file.h: note: this is the location of the previous definition
#define MACRO current_value
Normalmente lo hago de esta manera:
$ gcc -dM -E - < /dev/null
Tenga en cuenta que algunas definiciones del preprocesador dependen de las opciones de la línea de comandos; puede probarlas agregando las opciones relevantes a la línea de comandos anterior. Por ejemplo, para ver qué opciones de SSE3 / SSE4 están habilitadas de forma predeterminada:
$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1
y luego compare esto cuando se especifica -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 manera similar, puede ver qué opciones difieren entre dos conjuntos diferentes de opciones de línea de comando, por ejemplo, comparar las definiciones de preprocesador 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
Sí, use las opciones -E -dM
lugar de -c. Ejemplo (los envía a stdout):
gcc -dM -E - < /dev/null
Para C ++
g++ -dM -E -x c++ - < /dev/null
Desde el 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.
Un enfoque portátil que funciona igualmente 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 indicando a gcc que preprocese la entrada estándar (que es producida por echo) e imprima todas las definiciones del preprocesador (búsqueda de -dletters
). Si desea saber qué definiciones 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 <stdlib.h>" | 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
.
Respuesta tardía: las otras respuestas me parecieron útiles y quería agregar un poco más.
¿Cómo vuelco las macros del preprocesador que vienen de un archivo de encabezado particular?
echo "#include <sys/socket.h>" | gcc -E -dM -
En particular, quería ver qué SOMAXCONN estaba definido 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, solo puedo usar esta sola línea:
$ echo "#include <sys/socket.h>" | gcc -E -dM - | grep SOMAXCONN
#define SOMAXCONN 128
$