Le préprocesseur de vidage GCC définit

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

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

  gcc -dM -E - < /dev/null 

A partir du 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 savoir 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 un synonyme de -fdump-rtl-mach.

Je le fais habituellement 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 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-le 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 la même manière, vous pouvez voir quelles options diffèrent entre deux ensembles différents d’options de ligne de commande, par ex. Compare le 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 

Réponse tardive – j’ai trouvé les autres réponses utiles – et je voulais append un peu plus.


Comment vider les macros de préprocesseur provenant d’un fichier d’en-tête particulier?

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

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

 $ echo "#include " | gcc -E -dM - | 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 demandé 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/standing-documents/sd-6-sg10-feature-test-recommendations . Mais:

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

échoue toujours, car il invoque 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 supportera jamais les "Alias ​​de modèles" (voir http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ), vous devez append le -x c++ Option -x c++ pour forcer l'invocation du compilateur C ++ (Crédits pour l'utilisation des options -x c++ au lieu d'un fichier fictif vide pour 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, valeur 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'ils sont -std=c++11 avec -std=c++11 .

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

 echo | gcc -dM -E - 

Pour c ++, vous pouvez utiliser (remplacez c++11 avec la version que vous utilisez):

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

Il fonctionne en indiquant à gcc de prétraiter stdin (qui est produit par echo) et d’ imprimer toutes les définitions du préprocesseur (recherche de -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 les macros prédéfinies:

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

Notez toutefois que cette entrée vide produit encore beaucoup de définitions avec l’option -dD .

Tout en travaillant sur un gros 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 manière de voir le résultat de l’extension de la macro. 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