Ответы:
Да, используйте -E -dM
опции вместо -c. Пример (выводит их в стандартный вывод):
gcc -dM -E - < /dev/null
Для C ++
g++ -dM -E -x c++ - < /dev/null
Из руководства gcc :
Вместо обычного вывода создайте список директив #define для всех макросов, определенных во время выполнения препроцессора, включая предопределенные макросы. Это дает вам возможность узнать, что предопределено в вашей версии препроцессора. Предполагая, что у вас нет файла foo.h, команда
touch foo.h; cpp -dM foo.h
покажет все предопределенные макросы.
Если вы используете -dM без опции -E, -dM интерпретируется как синоним -fdump-rtl-mach.
echo | gcc -dM -E -
работает и на windows.
cpp -dM -E - < NUL
могут быть использованы.
Я обычно делаю это так:
$ 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
Поздний ответ - я нашел другие ответы полезными - и хотел добавить немного больше.
Как вывести дамп макроса препроцессора из определенного заголовочного файла?
echo "#include <sys/socket.h>" | gcc -E -dM -
или (спасибо @mymedia за предложение):
gcc -E -dM -include sys/socket.h - < /dev/null
В частности, я хотел посмотреть, что SOMAXCONN было определено в моей системе. Я знаю, что могу просто открыть стандартный файл заголовка, но иногда мне нужно немного поискать, чтобы найти расположение файла заголовка. Вместо этого я могу просто использовать эту строку:
$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$
Простой подход ( 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 ++ (Кредиты для использования -x c++
опций вместо пустого пустого файла идут в yuyichao, см. ниже):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
Вывод не будет, потому что g ++ (ревизия 4.9.1, по умолчанию -std = gnu ++ 98) не включает функции C ++ 11 по умолчанию. Для этого используйте
g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
что в итоге дает
#define __cpp_alias_templates 200704
отмечая, что g ++ 4.9.1 поддерживает «псевдонимы шаблонов» при вызове с -std=c++11
.
-x
аргумент, поэтому g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cpp
должен работать.
Переносимый подход, который одинаково хорошо работает в Linux или Windows (где нет / dev / null):
echo | gcc -dM -E -
Для c ++ вы можете использовать (замените c++11
на любую версию, которую вы используете):
echo | gcc -x c++ -std=c++11 -dM -E -
Он работает, сообщая gcc препроцессору stdin (который создается echo) и печатает все определения препроцессора (поиск -dletters
). Если вы хотите знать, какие определения добавляются, когда вы включаете заголовочный файл, вы можете использовать -dD
опцию, которая похожа на -dM, но не включает предопределенные макросы:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
Обратите внимание, однако, что пустой ввод по-прежнему производит много определений с -dD
опцией.
NUL
, вы вернетесь к исходной точке: он не будет работать в системах, в которых его нет.
sort
ведет себя немного иначе):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Работая в большом проекте, который имеет сложную систему сборки и где трудно получить (или изменить) команду gcc / g ++ напрямую, есть другой способ увидеть результат раскрытия макроса. Просто переопределите макрос, и вы получите вывод, похожий на следующий:
file.h: note: this is the location of the previous definition
#define MACRO current_value