web-dev-qa-db-fra.com

Le préprocesseur de vidage GCC définit

Existe-t-il un moyen pour gcc/g ++ de vider ses définitions de préprocesseur à partir de la ligne de commande? Je veux dire des choses comme __GNUC__, __STDC__, etc.

228
Anycorn

Oui, utilisez les options -E -dM au lieu de -c. Exemple (les sort sur stdout):

 gcc -dM -E - < /dev/null

Pour C++

 g++ -dM -E -x c++ - < /dev/null

Depuis le manuel gcc :

Au lieu de la sortie normale, générez une liste de directives `#define 'pour toutes les macros définies lors de l'exécution du pré-processeur, y compris les macros prédéfinies. Cela vous permet de déterminer ce qui est prédéfini dans votre version du préprocesseur. En supposant que vous n’ayez pas de fichier foo.h, la commande

touch foo.h; cpp -dM foo.h

montrera toutes les macros prédéfinies.

Si vous utilisez -dM sans l'option -E, -dM est interprété comme un synonyme de -fdump-rtl-mach.

280
philant

Je le fais habituellement de cette façon:

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

Notez que certaines définitions du préprocesseur dépendent des options de la ligne de commande. Vous pouvez les tester en ajoutant les options appropriées à la ligne de commande ci-dessus. Par exemple, pour voir quelles options SSE3/SSE4 sont activées par défaut:

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

puis comparez ceci lorsque -msse4 est spécifié:

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

De même, vous pouvez voir quelles options diffèrent entre deux ensembles différents d’options en ligne de commande, par exemple. compare les définitions du préprocesseur pour les niveaux d'optimisation -O0 (aucun) et -O3 (complet):

$ 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
76
Paul R

Réponse tardive - J'ai trouvé les autres réponses utiles - et je voulais ajouter un peu plus.


Comment puis-je vider les macros du préprocesseur provenant d'un fichier d'en-tête particulier?

echo "#include <sys/socket.h>" | gcc -E -dM -

En particulier, je voulais voir à quoi SOMAXCONN était défini sur mon système. Je sais que je pourrais simplement ouvrir le fichier d'en-tête standard, mais je dois parfois chercher un peu pour trouver l'emplacement du fichier d'en-tête. Au lieu de cela, je peux simplement utiliser ce one-liner:

$ echo "#include <sys/socket.h>" | gcc -E -dM - | grep SOMAXCONN
#define SOMAXCONN 128
$ 
39
Digital Trauma

L'approche simple (gcc -dM -E - < /dev/null) fonctionne bien pour gcc mais échoue pour g ++. Récemment, j'ai demandé un test pour une fonctionnalité C++ 11/C++ 14. Les recommandations concernant les noms de macro correspondants sont publiées à l’adresse suivante: https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations . Mais:

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

échoue toujours, car silencieusement appelle les pilotes C (comme s'ils étaient invoqués par gcc). Vous pouvez le voir en comparant sa sortie à celle de gcc ou en ajoutant une option de ligne de commande spécifique à g ++ telle que (-std = c ++ 11) qui émet le message d'erreur cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C.

Parce que (le non-C++), gcc ne supportera jamais "Alias ​​de modèles" (voir http://www.open-std.org/ jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ) vous devez ajouter l’option -x c++ pour forcer l’invocation du compilateur C++ (crédits permettant d’utiliser les options -x c++ au lieu de un fichier factice vide aller à yuyichao, voir ci-dessous):

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

Il n'y aura pas de sortie car g ++ (révision 4.9.1, par défaut -std = gnu ++ 98) n'active pas les fonctionnalités C++ 11 par défaut. Pour ce faire, utilisez

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

qui donne finalement

#define __cpp_alias_templates 200704

notant que g ++ 4.9.1 prend en charge les "alias de modèles" lorsqu'il est appelé avec -std=c++11.

30
hermannk

Une approche portable qui fonctionne aussi bien sous Linux que Windows (où il n'y a pas de/dev/null):

echo | gcc -dM -E -

Pour c ++, vous pouvez utiliser (remplacer c++11 avec la version de votre choix):

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

Cela fonctionne en disant à gcc de prétraiter stdin (qui est produit par echo) et affiche toutes les définitions du préprocesseur (recherche -dletters). Si vous voulez savoir quelles définitions sont ajoutées lorsque vous incluez un fichier d'en-tête, vous pouvez utiliser l'option -dD qui est similaire à -dM mais n'inclut pas de macros prédéfinies:

echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -

Notez cependant que cette entrée vide produit toujours beaucoup de définitions avec l'option -dD.

22
Pavel

Lorsque vous travaillez dans un grand projet qui a un système de construction complexe et où il est difficile d’obtenir (ou de modifier) ​​directement la commande gcc/g ++, il existe un autre moyen de voir le résultat de l’expansion des macros. Redéfinissez simplement la macro et vous obtiendrez une sortie similaire à celle-ci:

file.h: note: this is the location of the previous definition
#define MACRO current_value
2
Piotr Pałucki