2010-02-08 7 views

ответ

235

Да, используйте опции -E -dM вместо -c. Пример (выводит их на стандартный вывод):

gcc -dM -E - < /dev/null 

От gcc manual:

Вместо нормальной выходной мощности, генерируют список из директивы `#define» для всех макросов, определенных в ходе выполнение препроцессора, включая предопределенные макросы. Это дает вам способ узнать, что такое , предопределенный в вашей версии препроцессора . Предполагая, что у вас нет файла foo.h, команда

touch foo.h; cpp -dM foo.h 

покажет все предопределенные макросы.

Если вы используете -dM без опции -E, -dM интерпретируется как синоним -fdump-rtl-mach.

+2

НКУ существует в системах, где/DEV/нуль ничего не значит. – Pavel

+3

@Pavel, то вы можете использовать пустой файл, либо с gcc, либо с препроцессором - cpp. – philant

+15

Я добавил в качестве альтернативного ответа более портативный подход: 'echo | gcc -dM -E -' работает и с окнами. – Pavel

71

Я обычно делаю это так:

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

Обратите внимание, что некоторые препроцессора определяет, зависят от параметров командной строки - вы можете проверить это, добавив соответствующие параметры в командной строке выше. Например, чтобы увидеть, какие SSE3/SSE4 опции включены по умолчанию:

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

, а затем сравнить это когда -msse4 указано:

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

Аналогично вы можете увидеть, какие параметры отличаются между двумя различными наборами параметры командной строки, например сравнить препроцессор определяет для уровней оптимизации -O0 (нет) и -O3 (полное):

$ 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

Поздний ответ - я нашел другие ответы полезной - и хотел бы добавить немного дополнительных.


Как я свалка препроцессора макросы, поступающие из конкретного файла заголовка?

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

В частности, я хотел бы видеть, что SOMAXCONN была определена в моей системе. Я знаю, что могу просто открыть стандартный заголовочный файл, но иногда мне приходится немного искать его, чтобы найти расположение файлов заголовков.Вместо этого я могу просто использовать эту Однострочник:

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

Более портативный подход, который работает одинаково хорошо на Windows (в которой нет/DEV/нуль) или Linux:

echo | gcc -dM -E - 
+5

@rubenvb это не имеет значения. Дело в том, чтобы иметь cmd-линию, которая одинаково хорошо работает на windows и unix. Если вы используете 'NUL', вы вернетесь к квадрату: он не будет работать на системах, которые его не имеют. – Pavel

+0

, добавляющий полный ответ для C++, работает как на Windows, так и на Linux (хотя 'sort' ведет себя немного иначе):' echo | gcc -x C++ -std = C++ 17 -dM -E - | sort' – Xeverous

25

Простой подход (gcc -dM -E - < /dev/null) отлично работает для gcc, но не работает для g ++. Недавно мне потребовался тест для C++ 11/C++ 14. Рекомендации для их соответствующих имен макросов публикуются по адресу https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations. Но:

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

всегда терпит неудачу, потому что молча вызывает C-драйверов (как если вызывается gcc). Вы можете увидеть это, сравнив его вывод с файлом gcc или добавив параметр командной строки g ++, подобный (-std = C++ 11), который испускает сообщение об ошибке cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C.

Потому что (не C++) GCC будет никогда поддержки «Псевдонимы шаблонов» (см http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf), вы должны добавить опцию -x c++ заставить вызов компилятора C++ (Credits для использования -x c++ вариантов вместо пустой соски файл перейти к yuyichao, смотрите ниже):

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

Там не будет никакого вывода, поскольку г ++ (версия 4.9.1, по умолчанию -std = гну ++ 98) не позволяет C++ 11-функции по умолчанию , Для этого используйте

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

, который, наконец, дает

#define __cpp_alias_templates 200704 

, отметив, что г ++ 4.9.1 не поддерживает "псевдонимов шаблонов" при вызове с -std=c++11.

+6

Вам не нужно использовать фиктивный файл. GCC поддерживает аргумент '-x', поэтому' g ++ -x C++ -dM -E -std = C++ 11 - yuyichao

+0

@yuyichao Спасибо, это облегчает использование. Я не знал о опции -x. Добавил комментарий и интегрировал его в исходный ответ. – hermannk

0

При работе в большом проекте, который имеет сложную систему сборки и где трудно получить (или изменить) команду gcc/g ++, есть другой способ увидеть результат макрораспределения. Просто переопределить макрос, и вы получите на выходе похож на следующее:

file.h: note: this is the location of the previous definition 
#define MACRO current_value 
Смежные вопросы