列举C语言常量/宏

10

有没有一种方法可以让GNU C预处理器cpp(或其他工具)在给定C文件的某个点上列出所有可用的宏及其值?

我正在移植一个已经掌握Unix技能并加载了一些稀疏的Unix系统文件的程序,正在寻找特定于系统的宏。

只是想知道是否有比寻找定义更容易的方法。


3
一个有趣的问题......也许包括你的意图会获得更好的答案? - fbrereto
5个回答

16

我不知道文件中的某个位置,但是可以使用:

$ touch emptyfile
$ cpp -dM emptyfile
倾泻所有默认设置。对于带有一些#include#define行的C文件,执行相同操作也会包含它们。我想你可以将文件截断到你关心的地方,然后做同样的操作吗?
来自man页面-dCHARS CHARS是一个或多个以下字符序列,并且不能以空格开头。其他字符由编译器本身解释,或保留供未来版本的GCC使用,因此会被忽略。如果指定的字符的行为冲突,则结果未定义。 M 生成一个#define指令列表,用于记录预处理期间定义的所有宏,包括预定义宏。这样可以找出预处理程序版本中预定义的内容。假设没有名为foo.h的文件,则命令为:
    touch foo.h; cpp -dM foo.h

这将显示所有预定义宏。

如果您使用-dM而不使用-E选项,则-dM将被解释为-fdump-rtl-mach的同义词。

D
M相似,但有两个方面不同:它不包括预定义宏,并输出#define指令和预处理结果。这两种输出都传输到标准输出文件。

N
D相似,但仅发出宏名称,而不是其展开。

I
除了预处理结果之外还输出#include指令。


5
最快、最简单的方法是在不使用虚拟文件的情况下执行以下命令:gcc -dM -E - < /dev/null - Paul R
2
@Paul R:cpp -dM /dev/null 对我来说很有效... 看起来甚至更简单、更快,至少在考虑输入的努力方面... :-) - FooF
@Paul R - 确实很有趣;gcc 给出了 /dev/null: file not recognized: File truncated。顺便说一下,我看了答案,忽略了你实际上使用的是 gcc -E 而不是答案中的方式。我无法发现与 __STDC__ 相关的任何差异(x86_64gcc 4.6.1)。 - FooF
@FooF:我在使用cpp方法时得到了__STDC__ = 1,但是在使用gcc/g++方法时它没有被定义 - 这是在OS X上使用gcc/g++ 4.2.1时的情况。 - Paul R
@Paul R: cpp -dM /dev/null | grep __STDC__ --> #define __STDC__ 1。这是在gcc 4.6.{1,3} Ubuntu Linux上的情况。对于针对MIPS/ARM + uClibc的各种交叉编译器,基于GCC 4.{1.1,2.4,5.0,6.x,7.x},无论是cpp还是gcc都会给出#define __STDC__ 1(3.3.5没有定义#define __STDC__)。可能是OS X GCC配置上的一些差异...? - FooF
显示剩余3条评论

1

使用gcc,您可以使用"-dD"选项将所有宏定义转储到标准输出。


0
为什么不查阅预定义宏部分?您需要这个来构建项目或类似的东西吗?

是的,预定义宏是gcc手册的一个好章节,但我正在移植一个已经熟悉unix并加载了一些稀疏的unix系统文件的程序,所以我正在寻找特定于系统的宏。只是想知道是否有比寻找定义更简单的方法。 - ZJR

0

使用宏列出"C文件中特定点的值",有两种可以展示C文件中的给定点,尤其适用于跟踪故障点。考虑在名为foo.c的文件中使用以下示例代码:

if (!(ptr = malloc(20))){
    fprintf(stderr, "Whoops! Malloc Failed in %s at line %d\n", __FILE__, __LINE__);
}

如果该代码逻辑在该文件中被多次使用,并且调用malloc失败,则会得到此输出:

Whoops! Malloc Failed in foo.c at line 25

行号将根据源代码中该逻辑使用的位置而不同。此示例用于展示宏可用的位置。


0

这里有一个链接,其中概述了大多数编译器(gccclang等)用于列出预定义宏的命令行选项


...答案始终是“-d”。这个问题在5年前就已经被回答了,RTFM的死灵法师。我不明白这个答案的目的。 - ZJR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接