Definisce il preprocessore del dump GCC


248

C'è un modo per gcc / g ++ di scaricare il suo preprocessore definito dalla riga di comando? I cose meschine come __GNUC__, __STDC__e così via.

Risposte:


304

Sì, usa le -E -dMopzioni 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.


4
gcc esiste su sistemi in cui / dev / null non significa nulla.
Pavel P,

4
@Pavel quindi puoi usare un file vuoto, con gcc o il preprocessore - cpp.
filante

16
Ho aggiunto un approccio più portatile come risposta alternativa: echo | gcc -dM -E -funziona anche su Windows.
Pavel P,

4
È possibile determinare da dove (cioè in quale file) provengono queste definizioni?
edam,

2
In alternativa, su Windows, cpp -dM -E - < NULpuò essere utilizzato.
René Nyffenegger

78

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 -msse4viene 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

45

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
$ 

1
puoi usare l' opzione del compilatore -include per evitare pipe
mymedia

31

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.


7
Non è necessario utilizzare un file fittizio. GCC supporta l' -xargomento, quindi g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cppdovrebbe funzionare.
yuyichao,

@yuyichao Grazie, questo semplifica l'utilizzo. Non ero a conoscenza dell'opzione -x. Il tuo commento è stato votato e integrato nella risposta originale.
Hermannk,

23

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++11con 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 -dDun'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' -dDopzione.


6
@rubenvb è irrilevante. il punto è avere una linea cmd che funzioni ugualmente bene su Windows e almeno unix. Se lo usi NUL, torni al punto di partenza: non funzionerà su sistemi che non lo hanno.
Pavel P

2
aggiungendo la risposta completa per C ++, funziona sia su Windows che su Linux (sebbene sortsi comporti in modo leggermente diverso):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Xeverous,

Questo produce output vuoto in git-bash.
Lennart Rolland,

@LennartRolland ha gcc? Nel mio git-bash non posso eseguire gcc
Pavel P

@pavel Uso mccw32 gcc fornito con la distribuzione binaria Qt5 per Windows.
Lennart Rolland,

3

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

Sto cercando quale bandiera di avviso viene utilizzata per questo. Lo sai ?
Welgriv,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.