如何使用 gcc 显示预处理的宏(只是用户定义的)?

Posted

技术标签:

【中文标题】如何使用 gcc 显示预处理的宏(只是用户定义的)?【英文标题】:How do I display pre-processed macro (just user defined) using gcc? 【发布时间】:2015-05-21 23:14:50 【问题描述】:

我知道“gcc -E main.c”选项给出了所有值的预处理输出。有没有办法只扩展用户定义的宏?

例如

#define MACRO(z) z+z

c = a + (MACRO(z))

当我使用这个假设的 gcc 选项时,我应该看到:

c = a + (z+z)

我不希望扩展任何其他系统定义的宏。 GCC中有选项吗?

【问题讨论】:

什么是用户定义的宏?它只是写在这个源文件中的那些吗?或者它是否在用户定义的标题中包含宏(与系统定义的标题相反)?一种可能性可能是将#include 映射到@include(为了论证),然后使用gcc -E,如有必要,将@include 重新映射回#include。我不确定还有很多其他方法可以做到这一点。您可以有选择地只映射#include <angel-brackets.h>,而单独留下#include "double-quotes.h",以便扩展其中的宏(以及其他副作用)。 您还可以查看Coan 中的技术。 @Jonathan:不仅仅是源文件宏,用户定义的头文件中的宏也是。例如,假设您正在编写一个包含宏的文件,并且您想查看在预处理后宏的使用是如何形成的。我现在不需要这些信息,因为我正在尝试一个更简单的示例并且已经解决了它。但我记得在大学里使用带有 g++ 的标志,它只会用用户定义的宏吐出预处理代码。当我们使用多行宏来模拟“模板(c++)”时,它真的很有用。思想会更容易在互联网上找到。但没有运气。 :( 我害怕那个;它使处理变得非常复杂(因为要使用@include 技巧,您必须映射通过#include "header.h" 包含的文件的副本。这就是它没有作为标准完成的原因。我不确定你在大学里可能使用过哪个标志——它听起来不像是标准标志,或者你可以通过转到GCC documentation,阅读相关的 CPP 手册找到它(例如CPP 5.1.0 "Invocation" )。 【参考方案1】:

实际上,您想要做的是让预处理器忽略打开包含文件的错误。我认为有一个具有这种功能的编译器,但不是 GCC。 (或者我可能会将它与 GCC 功能混淆,以在生成依赖文件时忽略丢失的包含文件。)

但是,您可以做的是创建一个空文件的影子目录,该目录与系统头文件的所有名称和子目录匹配。然后您可以使用-nostdinc(忽略系统包含目录)和-I 选项(指向您的新影子目录)。

影子目录可以通过以下方式创建:

mkdir $HOME/tmp/emptystdinc
cd $HOME/tmp/emptystdinc
find /usr/include -type d -print | sed 's|/usr/include|.|' | xargs mkdir -p
find /usr/include -type f -print | sed 's|/usr/include|.|' | xargs touch

现在看看你的后处理代码是什么样子的:

cc -E -nostdinc -I$HOME/tmp/emptystdinc test.c

祝你好运!这对我来说很好用!

【讨论】:

【参考方案2】:

引用 cpp 手册页:

-undef 不要预定义任何系统特定或 GCC 特定的宏。标准的预定义宏保持定义。

这意味着__FILE____LINE__ 等宏将被扩展,但这可能足以满足您的需求。您还可以使用-U 取消定义这些标准的预定义宏。完整列表可以在here找到。

【讨论】:

这可能是解决方案的一部分,但您可能必须对 #include <stdio.h> 等中包含的宏做一些事情。 确实如此。由于 OP 在他的问题中没有使用#include,我不太确定。许多人滥用 C 预处理器以获取其他方式,在这种情况下,他们不使用系统头文件。

以上是关于如何使用 gcc 显示预处理的宏(只是用户定义的)?的主要内容,如果未能解决你的问题,请参考以下文章

GCC 使用 -D 参数定义类似函数的宏

宏编程是啥?

GCC使用-D参数定义类似函数的宏

gcc编译汇编源码时怎样支持#define宏定义

C语言学习笔记--C语言中的宏定义

gcc中预定义的宏__GNUC__