gcc / g ++是否有办法从命令行转储其预处理器定义?
我的意思是__GNUC__
,__STDC__
等等。
答案 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