GCC dump preprocesor definiuje

Czy istnieje sposób, aby gcc / g++ zrzucał swoje preprocesory zdefiniowane z linii poleceń? Mam na myśli rzeczy takie jak __GNUC__, __STDC__, i tak dalej.

Author: Brian Tompsett - 汤莱恩, 2010-02-08

6 answers

Tak, użyj opcji -E -dM zamiast-c. Przykład (wyprowadza je na stdout):

 gcc -dM -E - < /dev/null

Dla C++

 g++ -dM -E -x c++ - < /dev/null

Z instrukcji gcc :

Zamiast normalnego wyjścia, Generuj lista dyrektyw '# define' dla wszystkich makra zdefiniowane podczas wykonanie preprocesora, w tym predefiniowane makra. To pozwala dowiedzieć się, co jest predefiniowane w Twojej wersji preprocesor. Zakładając, że nie masz / align= "left" / h, the polecenie

touch foo.h; cpp -dM foo.h

Wyświetli wszystkie predefiniowane makra.

Jeśli używasz -dM bez opcji-E, -dM jest interpretowany jako synonim-fdump-rtl-mach.

 322
Author: philant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-21 16:59:26

Zwykle robię to w ten sposób:

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

Zauważ, że niektóre definicje preprocesora zależą od opcji wiersza poleceń - możesz je przetestować, dodając odpowiednie opcje do powyższego wiersza poleceń. Na przykład, aby sprawdzić, które opcje SSE3/SSE4 są domyślnie włączone:

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

A następnie porównaj to, gdy -msse4 jest określone:

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

Podobnie można zobaczyć, które opcje różnią się między dwoma różnymi zestawami opcji wiersza poleceń, np. porównaj preprocesor definiuje dla poziomy optymalizacji -O0 (Brak) i -O3 (pełna):

$ 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
 80
Author: Paul R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-19 12:40:09

późna odpowiedź-inne odpowiedzi okazały się przydatne - i chciałem dodać trochę więcej.


Jak zrzucić makra preprocesora pochodzące z określonego pliku nagłówkowego?

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

Lub (dzięki @mymedia za sugestię):

gcc -E -dM -include sys/socket.h - < /dev/null
W szczególności chciałem zobaczyć, do czego SOMAXCONN został zdefiniowany w moim systemie. Wiem, że mogę po prostu otworzyć standardowy plik nagłówka, ale czasami muszę trochę przeszukać, aby znaleźć lokalizacje plików nagłówkowych. Zamiast Tego Ja można po prostu użyć tej jednowierszowej:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$ 
 47
Author: Digital Trauma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-11 18:27:07

Proste podejście (gcc -dM -E - < /dev/null) działa dobrze dla gcc, ale zawodzi dla g++. Ostatnio wymagałem testu dla funkcji C++11/C++14. Zalecenia dotyczące odpowiadających im nazw makr są publikowane na stronie https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations . Ale:

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

Zawsze zawodzi, ponieważ po cichu wywołuje sterowniki C (jakby wywoływane przez gcc). Możesz to zobaczyć porównując jego wyjście z GCC lub dodając specyficzny dla g++ opcja wiersza poleceń, taka jak (- std=c++11), która emituje komunikat o błędzie cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C.

Ponieważ (nie C++) gcc będzie nigdy wspierać "aliasy szablonów" (patrz http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf) musisz dodać opcję -x c++, aby wymusić wywołanie kompilatora C++ (kredyty za użycie opcji -x c++ zamiast pustego atrapowego pliku przejdź do yuyichao, patrz poniżej):

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

Nie będzie wyjścia, ponieważ g++ (Wersja 4.9.1, domyślnie-std = gnu++98) domyślnie nie włącza funkcji C++11. Aby to zrobić, użyj

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

Który ostatecznie daje

#define __cpp_alias_templates 200704

Zauważając, że g++ 4.9.1 obsługuje "aliasy szablonów" podczas wywoływania z -std=c++11.

 33
Author: hermannk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-17 07:37:27

Przenośne podejście, które działa równie dobrze na Linuksie lub Windows (gdzie nie ma /dev/null):

echo | gcc -dM -E -

Dla c++ możesz użyć (zamień c++11 na dowolną wersję):

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

Działa poprzez polecenie gcc, aby preprocesował stdin (który jest produkowany przez echo) i wypisuje wszystkie preprocesory definiuje (wyszukaj -dletters). Jeśli chcesz wiedzieć, co definiuje dodane podczas dołączania pliku nagłówkowego możesz użyć opcji -dD, która jest podobna do-dM, ale nie Dołącz predefiniowane makra:

echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -

Zauważ jednak, że puste wejście nadal generuje wiele definicji z opcją -dD.

 25
Author: Pavel P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-30 05:05:16

Podczas pracy w dużym projekcie, który ma złożony system budowania i gdzie trudno jest uzyskać (lub zmodyfikować) polecenie gcc/g++ bezpośrednio, istnieje inny sposób, aby zobaczyć wynik rozszerzenia makr. Po prostu przedefiniuj makro, a otrzymasz wynik podobny do następującego:

file.h: note: this is the location of the previous definition
#define MACRO current_value
 3
Author: Piotr Pałucki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 10:48:11