GCC转储预处理器定义

时间:2010-02-08 19:40:29

标签: gcc g++ c-preprocessor

gcc / g ++是否有办法从命令行转储其预处理器定义? 我的意思是__GNUC____STDC__等等。

6 个答案:

答案 0 :(得分:273)

是的,使用-E -dM选项而不是-c。 示例(将它们输出到stdout):

 gcc -dM -E - < /dev/null

对于C ++

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

来自gcc manual

  

而不是正常输出,生成   所有人的“#define”指令列表   在期间定义的宏   执行预处理器,   包括预定义的宏。这个   为您提供一种找出问题的方法   在您的版本中预定义   预处理。假设你没有   文件foo.h,命令

touch foo.h; cpp -dM foo.h
     

将显示所有预定义的宏。

     

如果在没有-E选项的情况下使用-dM,   -dM被解释为-fdump-rtl-mach。

的同义词

答案 1 :(得分:75)

我通常这样做:

$ 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

答案 2 :(得分:37)

迟到的答案 - 我发现其他答案很有用 - 并希望增加一些额外的答案。


如何转储来自特定头文件的预处理器宏?

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

特别是,我想看看SOMAXCONN在我的系统中定义了什么。我知道我可以打开标准的头文件,但有时我必须搜索一下才能找到头文件的位置。相反,我可以使用这个单行:

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

答案 3 :(得分:30)

简单的方法(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调用时支持“模板别名”。

答案 4 :(得分:22)

一种便携式方法,在Linux或Windows(没有/ dev / null)上同样有效:

echo | gcc -dM -E -

对于c ++,您可以使用(将c++11替换为您使用的任何版本):

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

它通过告诉gcc预处理stdin(由echo产生)和print all preprocessor defines(搜索-dletters)来工作。如果您想知道在包含头文件时添加的定义,您可以使用类似于-dM但不包含预定义宏的-dD选项:

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

但请注意,空输入仍会产生大量带有-dD选项的定义。

答案 5 :(得分:2)

在一个具有复杂构建系统且难以直接获取(或修改)gcc / g ++命令的大型项目中工作时,还有另一种方法可以查看宏扩展的结果。 只需重新定义宏,您将获得与以下类似的输出:

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