Препроцессор дампа GCC определяет - PullRequest
226 голосов
/ 08 февраля 2010

Есть ли способ для gcc / g ++ выгружать свои определения препроцессора из командной строки? Я имею в виду такие вещи, как __GNUC__, __STDC__ и так далее.

Ответы [ 6 ]

275 голосов
/ 08 февраля 2010

Да, используйте опции -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.

75 голосов
/ 08 февраля 2010

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

$ 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
37 голосов
/ 05 ноября 2013

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


Как вывести дамп макроса препроцессора из определенного заголовочного файла?

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

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

$ echo "#include <sys/socket.h>" | gcc -E -dM - | grep SOMAXCONN
#define SOMAXCONN 128
$ 
30 голосов
/ 16 января 2015

Простой подход (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 / paper / 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.

22 голосов
/ 12 января 2014

Переносимый подход, который одинаково хорошо работает в Linux или Windows (где нет / dev / null):

echo | gcc -dM -E -

Для c ++ вы можете использовать (замените c++11 на любую версию, которую вы используете):

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

Он работает, сообщая gcc препроцессору stdin (который создается echo) и print, определяющий все препроцессоры (поиск -dletters).Если вы хотите знать, что определяет добавление , когда вы включаете заголовочный файл, вы можете использовать опцию -dD, которая похожа на -dM, но не включает предопределенные макросы:

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

Обратите внимание, однако, что пустой ввод по-прежнему производит много определений с опцией -dD.

2 голосов
/ 25 августа 2017

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

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