Risposte:
Sì, usa le -E -dM
opzioni invece di -c. Esempio (li emette su stdout):
gcc -dM -E - < /dev/null
Per C ++
g++ -dM -E -x c++ - < /dev/null
Dal manuale di gcc :
Invece del normale output, genera un elenco di direttive `#define 'per tutte le macro definite durante l'esecuzione del preprocessore, comprese le macro predefinite. Questo ti dà un modo per scoprire cosa è predefinito nella tua versione del preprocessore. Supponendo di non avere alcun file foo.h, il comando
touch foo.h; cpp -dM foo.h
mostrerà tutte le macro predefinite.
Se si utilizza -dM senza l'opzione -E, -dM viene interpretato come sinonimo di -fdump-rtl-mach.
echo | gcc -dM -E -
funziona anche su Windows.
cpp -dM -E - < NUL
può essere utilizzato.
Di solito lo faccio in questo modo:
$ gcc -dM -E - < /dev/null
Si noti che alcune definizioni del preprocessore dipendono dalle opzioni della riga di comando: è possibile verificarle aggiungendo le opzioni pertinenti alla riga di comando sopra. Ad esempio, per vedere quali opzioni SSE3 / SSE4 sono abilitate per impostazione predefinita:
$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1
e quindi confrontare questo quando -msse4
viene specificato:
$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1
Allo stesso modo puoi vedere quali opzioni differiscono tra due diversi insiemi di opzioni della riga di comando, ad esempio confronta i parametri del preprocessore per i livelli di ottimizzazione -O0
(nessuno) e -O3
(completo):
$ 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
Risposta tardiva - ho trovato utili le altre risposte - e volevo aggiungere un po 'di più.
Come posso scaricare macro preprocessore provenienti da un particolare file di intestazione?
echo "#include <sys/socket.h>" | gcc -E -dM -
oppure (grazie a @mymedia per il suggerimento):
gcc -E -dM -include sys/socket.h - < /dev/null
In particolare, volevo vedere a cosa era definito SOMAXCONN sul mio sistema. So che potrei semplicemente aprire il file di intestazione standard, ma a volte devo cercare un po 'per trovare le posizioni dei file di intestazione. Invece posso solo usare questo one-liner:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$
L'approccio semplice ( gcc -dM -E - < /dev/null
) funziona bene per gcc ma fallisce per g ++. Di recente ho richiesto un test per una funzione C ++ 11 / C ++ 14. I consigli per i nomi delle macro corrispondenti sono pubblicati su https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations . Ma:
g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
fallisce sempre, perché invoca silenziosamente i driver C (come se invocato da gcc
). Puoi vederlo confrontando il suo output con quello di gcc o aggiungendo un'opzione specifica della riga di comando g ++ come (-std = c ++ 11) che emette il messaggio di errore cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
.
Perché (non C ++) gcc non supporterà mai "Alias modelli" (vedi http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf ) devi aggiungere l' -x c++
opzione a forzare l'invocazione del compilatore C ++ (i crediti per l'utilizzo delle -x c++
opzioni anziché un file fittizio vuoto vanno su yuyichao, vedi sotto):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
Non ci sarà output perché g ++ (revisione 4.9.1, il valore predefinito è -std = gnu ++ 98) per impostazione predefinita non abilita le funzionalità C ++ 11. Per fare ciò, utilizzare
g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
che alla fine cede
#define __cpp_alias_templates 200704
notando che g ++ 4.9.1 supporta "Alias modelli" quando viene invocato con -std=c++11
.
-x
argomento, quindi g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp
dovrebbe funzionare.
Un approccio portatile che funziona ugualmente bene su Linux o Windows (dove non c'è / dev / null):
echo | gcc -dM -E -
Per c ++ puoi usare (sostituisci c++11
con qualunque versione tu usi):
echo | gcc -x c++ -std=c++11 -dM -E -
Funziona dicendo a gcc di preelaborare stdin (che è prodotto da echo) e di stampare tutte le definizioni del preprocessore (cercare -dletters
). Se vuoi sapere quali sono le definizioni aggiunte quando includi un file di intestazione puoi usare -dD
un'opzione simile a -dM ma che non include macro predefinite:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
Si noti, tuttavia, che l'input vuoto produce ancora molte definizioni con l' -dD
opzione.
NUL
, torni al punto di partenza: non funzionerà su sistemi che non lo hanno.
sort
si comporti in modo leggermente diverso):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Mentre si lavora in un grande progetto che ha un sistema di compilazione complesso e in cui è difficile ottenere (o modificare) direttamente il comando gcc / g ++, c'è un altro modo per vedere il risultato dell'espansione delle macro. Ridefinisci semplicemente la macro e otterrai un output simile al seguente:
file.h: note: this is the location of the previous definition
#define MACRO current_value