【问题标题】:Partial preprocessing of C files with GCC (not removing "define" directives)使用 GCC 对 C 文件进行部分预处理(不删除“定义”指令)
【发布时间】:2020-03-07 10:48:39
【问题描述】:

如果我通过-E-save-temps 命令行参数,GCC 可以输出一个完全预处理的 C++ 源文件。

我的问题是,我能否以某种方式获得一个部分预处理的 C++ 源文件,其中

a) 排除不满足#if、#ifdef 和#ifndef 条件的代码片段,

b) #include 指令被解析(包括头文件),等等

但是

c) 普通的#define 指令没有解析?

(这将是必要的并且非常有用,因为我希望尽可能获得最紧凑和可读的输出。 解析#if 指令会缩短源代码,但解析#define 指令会降低源代码的可读性和冗余性。)

我试图创建一个尽可能紧凑的示例,以展示我想要实现的目标:

示例输入文件:

// header1.h
#ifndef header1_h
#define header1_h
int function1(int val) {
  return val + MYCONST;
}
#endif

// header2.h
#ifndef header2_h
#define header2_h
int function1(int val) {
  return val + val + MYCONST;
}
#endif

// main.c
#define MYCONST 1234
#define SETTING1
#ifdef SETTING1
  #include "header1.h"
#endif
#ifdef SETTING2
  #include "header2.h"
#endif
int main(void) {
  int retVal = function1(99);
}

预期输出:

// main.i (GCC preprocessing output)
#define MYCONST 1234 // I would like to see the definition of MYCONST here
#define SETTING1
#define header1_h
int function1(int val) {
  return val + MYCONST; // I would like to see MYCONST here instead of the resolved value
}
int main(void) {
  int retVal = function1(99);
}

【问题讨论】:

  • "Resolving" #include 指令会在你的文件中添加一个 lot。而对于系统头文件,您大多不会使用或不想阅读其中的大部分内容。
  • 您可以尝试使用 Boost.Wave 或类似的独立 PP 实现作为解决方案的起点。
  • 但是 (c) 和 (a) 可能相互依赖。
  • @RichardCritten 其实也是 (b),因为宏可用于包含。

标签: c++ gcc c-preprocessor


【解决方案1】:

gcc 有一个选项 -fdirectives only 可以做一些接近你想要的事情:

-fdirectives-only

预处理时,处理指令,但不要扩展宏。

选项的行为取决于 -E 和 -fpreprocessed 选项。

使用 -E,预处理仅限于处理 #define、#ifdef 和 #error 等指令。不执行其他预处理器操作,例如宏扩展和三字符转换。此外,隐式启用了 -dD 选项。

使用 -fpreprocessed,命令行和大多数内置宏的预定义被禁用。像__LINE__ 这样的宏是上下文相关的,可以正常处理。这样可以编译以前使用 -E -fdirectives-only 预处理过的文件。

如果同时使用 -E 和 -fpreprocessed,则 -fpreprocessed 的规则优先。这可以对之前使用 -E -fdirectives-only 预处理过的文件进行全面预处理。

在你的情况下,它应该被称为

 % gcc -fdirectives-only -E -o main.i main.c

但您得到的定义(内部定义的)、空行和#line 行比您要求的要多。

【讨论】:

  • 谢谢。它就像一个魅力。在花了这么多时间调试 simplecpp 的源代码和玩弄 coan 之后,我并不希望有这么简单的解决方案。显然空行、#line 行和 cmets 可以很容易地删除,如果没有列出内部定义的定义,图片就不会是完整的(这实际上是非常有益的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 2013-07-02
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
相关资源
最近更新 更多