Antworten:
Ja, verwenden Sie -E -dM
Optionen anstelle von -c. Beispiel (gibt sie an stdout aus):
gcc -dM -E - < /dev/null
Für C ++
g++ -dM -E -x c++ - < /dev/null
Aus dem gcc-Handbuch :
Generieren Sie anstelle der normalen Ausgabe eine Liste der Direktiven "#define" für alle Makros, die während der Ausführung des Präprozessors definiert wurden, einschließlich vordefinierter Makros. Auf diese Weise können Sie herausfinden, was in Ihrer Version des Präprozessors vordefiniert ist. Angenommen, Sie haben keine Datei foo.h, den Befehl
touch foo.h; cpp -dM foo.h
zeigt alle vordefinierten Makros an.
Wenn Sie -dM ohne die Option -E verwenden, wird -dM als Synonym für -fdump-rtl-mach interpretiert.
echo | gcc -dM -E -
unter Windows.
cpp -dM -E - < NUL
verwendet werden.
Normalerweise mache ich das so:
$ gcc -dM -E - < /dev/null
Beachten Sie, dass einige Präprozessordefinitionen von Befehlszeilenoptionen abhängen. Sie können diese testen, indem Sie die entsprechenden Optionen zur obigen Befehlszeile hinzufügen. So sehen Sie beispielsweise, welche SSE3 / SSE4-Optionen standardmäßig aktiviert sind:
$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1
und vergleichen Sie dies dann, wenn -msse4
angegeben:
$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1
In ähnlicher Weise können Sie sehen, welche Optionen sich zwischen zwei verschiedenen Sätzen von Befehlszeilenoptionen unterscheiden, z. B. Präprozessordefinitionen für Optimierungsstufen vergleichen -O0
(keine) und -O3
(vollständig):
$ 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
Späte Antwort - ich fand die anderen Antworten nützlich - und wollte ein bisschen mehr hinzufügen.
Wie speichere ich Präprozessor-Makros, die aus einer bestimmten Header-Datei stammen?
echo "#include <sys/socket.h>" | gcc -E -dM -
oder (danke an @mymedia für den Vorschlag):
gcc -E -dM -include sys/socket.h - < /dev/null
Insbesondere wollte ich sehen, wofür SOMAXCONN auf meinem System definiert ist. Ich weiß, dass ich einfach die Standard-Header-Datei öffnen könnte, aber manchmal muss ich ein bisschen suchen, um die Speicherorte der Header-Dateien zu finden. Stattdessen kann ich nur diesen Einzeiler verwenden:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$
Der einfache Ansatz ( gcc -dM -E - < /dev/null
) funktioniert gut für gcc, schlägt jedoch für g ++ fehl. Kürzlich habe ich einen Test für eine C ++ 11 / C ++ 14-Funktion benötigt. Empfehlungen für die entsprechenden Makronamen werden unter https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations veröffentlicht . Aber:
g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
schlägt immer fehl, weil es stillschweigend die C-Treiber aufruft (als ob von aufgerufen gcc
). Sie können dies sehen, indem Sie die Ausgabe mit der von gcc vergleichen oder eine g ++ - spezifische Befehlszeilenoption wie (-std = c ++ 11) hinzufügen, die die Fehlermeldung ausgibt cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
.
Da (nicht C ++) gcc niemals "Templates Aliases" unterstützt (siehe http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ), müssen Sie die -x c++
Option hinzufügen Erzwingen Sie den Aufruf des C ++ - Compilers (Credits für die Verwendung der -x c++
Optionen anstelle einer leeren Dummy-Datei gehen an yuyichao, siehe unten):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
Es erfolgt keine Ausgabe, da g ++ (Version 4.9.1, standardmäßig -std = gnu ++ 98) standardmäßig keine C ++ 11-Funktionen aktiviert. Verwenden Sie dazu
g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
was schließlich ergibt
#define __cpp_alias_templates 200704
Beachten Sie, dass g ++ 4.9.1 "Templates Aliases" unterstützt, wenn es mit aufgerufen wird -std=c++11
.
-x
Argument, g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp
sollte also funktionieren.
Ein portabler Ansatz, der unter Linux oder Windows gleich gut funktioniert (wo es kein / dev / null gibt):
echo | gcc -dM -E -
Für c ++ können Sie Folgendes verwenden (durch eine c++11
beliebige Version ersetzen ):
echo | gcc -x c++ -std=c++11 -dM -E -
Es funktioniert, indem gcc angewiesen wird, stdin (das von echo erzeugt wird) vorzuverarbeiten und alle Präprozessordefinitionen auszudrucken (Suche nach -dletters
). Wenn Sie wissen möchten, welche Definitionen hinzugefügt werden, wenn Sie eine Header-Datei -dD
einfügen, können Sie eine Option verwenden, die -dM ähnelt, jedoch keine vordefinierten Makros enthält:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
Beachten Sie jedoch, dass leere Eingaben immer noch viele Definitionen mit -dD
Option erzeugen .
NUL
, sind Sie wieder auf dem ersten Platz: Es funktioniert nicht auf Systemen, die es nicht haben.
sort
sich kaum unterscheidet):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Während Sie in einem großen Projekt arbeiten, das über ein komplexes Build-System verfügt und bei dem es schwierig ist, den Befehl gcc / g ++ direkt abzurufen (oder zu ändern), gibt es eine andere Möglichkeit, das Ergebnis der Makroerweiterung anzuzeigen. Definieren Sie das Makro einfach neu, und Sie erhalten eine Ausgabe ähnlich der folgenden:
file.h: note: this is the location of the previous definition
#define MACRO current_value