Réponses:
Oui, utilisez des -E -dM
options au lieu de -c. Exemple (les renvoie vers stdout):
gcc -dM -E - < /dev/null
Pour C ++
g++ -dM -E -x c++ - < /dev/null
Depuis le manuel de 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écouvrir ce qui est prédéfini dans votre version du préprocesseur. En supposant que vous n'avez pas de fichier foo.h, 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 synonyme de -fdump-rtl-mach.
echo | gcc -dM -E -
fonctionne également sur Windows.
cpp -dM -E - < NUL
peut être utilisé.
Je le fais généralement de cette façon:
$ gcc -dM -E - < /dev/null
Notez que certaines définitions de préprocesseur dépendent des options de ligne de commande - vous pouvez les tester 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 ceci quand -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 de ligne de commande, par exemple comparer les définitions de 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
Réponse tardive - j'ai trouvé les autres réponses utiles - et je voulais en ajouter un peu plus.
Comment vider les macros de préprocesseur provenant d'un fichier d'en-tête particulier?
echo "#include <sys/socket.h>" | gcc -E -dM -
ou (merci à @mymedia pour la suggestion):
gcc -E -dM -include sys/socket.h - < /dev/null
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 parfois je dois chercher un peu pour trouver les emplacements du fichier d'en-tête. Au lieu de cela, je peux simplement utiliser ce one-liner:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$
L'approche simple ( gcc -dM -E - < /dev/null
) fonctionne bien pour gcc mais échoue pour g ++. Récemment, j'ai eu besoin d'un test pour une fonctionnalité C ++ 11 / C ++ 14. Les recommandations pour leurs noms de macro correspondants sont publiées sur https://isocpp.org/std/stand-documents/sd-6-sg10-feature-test-recommendations . Mais:
g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
échoue toujours, car il appelle silencieusement les pilotes C (comme s'il était appelé par gcc
). Vous pouvez le voir en comparant sa sortie avec 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 (le non C ++) gcc ne prendra jamais en charge les "alias de modèles" (voir http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ), vous devez ajouter l' -x c++
option à forcer l'invocation du compilateur C ++ (les crédits pour l'utilisation des -x c++
options au lieu d'un fichier factice vide vont à 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
.
-x
argument et g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp
devrait donc fonctionner.
Une approche portable qui fonctionne aussi bien sous Linux ou Windows (où il n'y a pas / dev / null):
echo | gcc -dM -E -
Pour c ++, vous pouvez utiliser (remplacer c++11
par la version que vous utilisez):
echo | gcc -x c++ -std=c++11 -dM -E -
Il fonctionne en disant à gcc de prétraiter stdin (qui est produit par echo) et d' imprimer toutes les définitions de préprocesseur (rechercher -dletters
). Si vous voulez savoir quelles définitions sont ajoutées lorsque vous incluez un fichier d'en-tête, vous pouvez utiliser une -dD
option similaire à -dM mais qui n'inclut pas de macros prédéfinies:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
Notez cependant que l'entrée vide produit toujours beaucoup de définitions avec -dD
option.
NUL
, vous êtes de retour à la case départ: cela ne fonctionnera pas sur les systèmes qui ne l'ont pas.
sort
se comporte peu différemment):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Tout en travaillant 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 une autre façon de voir le résultat de l'expansion des macros. Redéfinissez simplement la macro et vous obtiendrez une sortie similaire à la suivante:
file.h: note: this is the location of the previous definition
#define MACRO current_value