2010-02-08 12 views

risposta

235

Sì, utilizzare le opzioni -E -dM anziché -c. Esempio (li riproduce stdout):

gcc -dM -E - < /dev/null 

Dal gcc manual:

posto della normale uscita, generare un elenco di direttive `#define' per tutti macro definite durante la esecuzione del preprocessore, compresi i macro predefiniti. Questo ti dà un modo di scoprire cosa è predefinito nella tua versione del preprocessore . Supponendo di avere alcun file di 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.

+2

gcc esiste nei sistemi in cui/dev/null non significa nulla. – Pavel

+3

@Pavel quindi è possibile utilizzare un file vuoto, con gcc o con il preprocessore - cpp. – philant

+15

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

71

Io di solito fare in questo modo:

$ gcc -dM -E - < /dev/null 

Nota che alcuni definisce preprocessore dipendono opzioni della riga di comando - è possibile testare questi aggiungendo le opzioni relative alla riga di comando di cui sopra. Ad esempio, per vedere quali opzioni SSE3/SSE4 sono abilitate di default:

$ gcc -dM -E - < /dev/null | grep SSE[34] 
#define __SSE3__ 1 
#define __SSSE3__ 1 

e quindi confrontare questo quando viene specificato -msse4:

$ 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 si può vedere quali opzioni si differenziano tra due diversi gruppi di opzioni della riga di comando, ad es confrontare preprocessore definisce per 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 
35

risposta tardi - ho trovato le altre risposte utili - e voluto aggiungere un po 'extra.


Come faccio a discarica macro del preprocessore provenienti da un particolare file di intestazione?

echo "#include <sys/socket.h>" | gcc -E -dM - 

In particolare, ho voluto vedere quello che è stato definito SOMAXCONN per il 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 io può semplicemente utilizzare questo one-liner:

$ echo "#include <sys/socket.h>" | gcc -E -dM - | grep SOMAXCONN 
#define SOMAXCONN 128 
$ 
15

Altro approccio portatile che funziona altrettanto bene su Windows (dove non c'è/dev/null) o Linux:

echo | gcc -dM -E - 
+5

@rubenvb è irrilevante. il punto è avere la linea cmd che funziona ugualmente bene su windows e unix almeno. Se usi 'NUL', torni al punto di partenza: non funzionerà su sistemi che non ce l'hanno. – Pavel

+0

aggiungendo una risposta completa per C++, funziona su Windows e Linux (anche se 'sort' si comporta in modo leggermente diverso):' echo | gcc -x C++ -std = C++ 17 -dM -E - | sort' – Xeverous

25

L'approccio semplice (gcc -dM -E - < /dev/null) funziona bene per gcc ma non riesce per g ++. Recentemente ho richiesto un test per una funzione C++ 11/C++ 14. I consigli per i corrispondenti nomi macro sono pubblicati allo 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é silenziosamente invoca il C-driver (come se invocato da gcc). Puoi vederlo confrontando il suo output con quello di gcc o aggiungendo un'opzione a riga di comando specifica per 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é (la non C++) gcc sarà mai sostegno "Modelli Alias" (vedi http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf) è necessario aggiungere l'opzione -x c++ per forzare l'invocazione del compilatore C++ (Crediti per l'utilizzo delle opzioni -x c++ invece di un manichino vuoto file vai al yuyichao, vedi sotto):

g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates 

non ci sarà alcuna uscita perché g ++ (revisione 4.9.1, il default è -STD = gnu ++ 98) non consente C++ 11-caratteristiche di default . Per fare ciò, utilizzare

g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates 

che produce infine

#define __cpp_alias_templates 200704 

notare che g ++ 4.9.1 supporta "Modelli alias" quando invocato con -std=c++11.

+6

Non è necessario utilizzare un file fittizio. GCC supporta l'argomento '-x' quindi' g ++ -x C++ -dM -E -std = C++ 11 - yuyichao

+0

@yuyichao Grazie, questo lo rende più facile da usare. Non ero a conoscenza dell'opzione -x. Hai aumentato il tuo commento e l'hai integrato nella risposta originale. – hermannk

0

Mentre si lavora in un grande progetto che ha un sistema di compilazione complesso e dove è difficile ottenere (o modificare) direttamente il comando gcc/g ++, c'è un altro modo per vedere il risultato dell'espansione macro. semplicemente ridefinire la macro, e si otterrà la classica uscita a seguire:

file.h: note: this is the location of the previous definition 
#define MACRO current_value 
Problemi correlati