Answers:
是的,使用-E -dM
选项代替-c。示例(将它们输出到stdout):
gcc -dM -E - < /dev/null
对于C ++
g++ -dM -E -x c++ - < /dev/null
从gcc手册:
代替正常输出,为在预处理器执行期间定义的所有宏(包括预定义宏)生成一个“ #define”指令列表。这使您可以找到在您的预处理器版本中预定义的内容。假设您没有文件foo.h,该命令
touch foo.h; cpp -dM foo.h
将显示所有预定义的宏。
如果使用不带-E选项的-dM,则-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
option 的定义。
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