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.
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.
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
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
$
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
.
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
.
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
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