2010-02-08 2 views

Répondre

235

Oui, utilisez les options -E -dM au lieu de -c. Exemple (les sorties à la sortie standard):

gcc -dM -E - < /dev/null 

De l'gcc manual:

au lieu de la sortie normale, générer une liste de directives `#define » pour toutes les macros définies au cours de la exécution du préprocesseur, y compris les macros prédéfinies. Cette vous donne un moyen de savoir ce qui est prédéfini dans votre version du préprocesseur . En supposant que vous n'avez pas foo.h de fichier , la commande

touch foo.h; cpp -dM foo.h 

affichera 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.

+2

gcc existe sur les systèmes où/dev/null ne signifie rien. – Pavel

+3

@Pavel alors vous pouvez utiliser un fichier vide, soit avec gcc ou le préprocesseur - cpp. – philant

+15

J'ai ajouté une approche plus portable comme réponse alternative: 'echo | gcc -dM -E -' fonctionne aussi bien sur Windows. – Pavel

71

je le fais habituellement de cette façon:

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

Notez que certains définit préprocesseur dépendent des options de ligne de commande - vous pouvez tester ces en ajoutant les options pertinentes à 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 comparer 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 de options de ligne de commande, par exemple comparer préprocesseur définit 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 
35

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


Comment puis-je larguer des macros préprocesseur provenant d'un fichier d'en-tête particulier?

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

Je voulais, en particulier, de voir ce que SOMAXCONN a été défini sur mon système. Je sais que je pourrais simplement ouvrir le fichier d'en-tête standard, mais parfois je dois chercher un peu pour trouver les emplacements des fichiers d'en-tête.Je peux plutôt juste utiliser ce one-liner:

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

Une approche plus portable qui fonctionne aussi bien sur Windows (où il n'y a pas/dev/null) ou Linux:

echo | gcc -dM -E - 
+5

@rubenvb c'est sans importance. le point est d'avoir une ligne cmd qui fonctionne aussi bien sur windows et unix au moins. Si vous utilisez 'NUL', vous revenez à la case départ: cela ne fonctionnera pas sur les systèmes qui ne l'ont pas. – Pavel

+0

ajoutant une réponse complète pour C++, fonctionne sur Windows et Linux (bien que 'sort' se comporte un peu différemment):' echo | gcc -x C++ -std = C++ 17 -dM -E - | sort' – Xeverous

25

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 pour leurs noms de macro correspondants sont publiées au 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 il silencieusement appelle les pilotes C-(comme si elle est invoquée 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 ++ comme (-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 (non C++) gcc jamais support « Alias ​​Templates » (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 pour l'utilisation des -x c++ options au lieu d'un mannequin vide aller à yuyichao déposer des, voir ci-dessous):

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

Il n'y aura pas de sortie parce que g ++ (révision 4.9.1, par défaut std = gnu ++ 98) ne permet pas de C++ 11-fonctionnalités 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 

noter que g ++ 4.9.1 ne supporte "Alias ​​Templates" lorsqu'il est appelé avec -std=c++11.

+6

Vous n'avez pas besoin d'utiliser un fichier fictif. GCC supporte l'argument '-x' donc' g ++ -x C++ -dM -E -std = C++ 11 - yuyichao

+0

@yuyichao Merci, cela rend l'utilisation plus facile. Je n'étais pas au courant de l'option -x. Upvoted votre commentaire et l'a intégré dans la réponse originale. – hermannk

0

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 de macros. redéfinissent simplement la macro, et vous obtiendrez de sortie similaire suivante:

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