默认情况下使用unifdef省略未定义的预处理器分支的方法?

我正在使用包含许多编译选项的复杂C代码。 这使得代码非常难以阅读。 我想生成一个反映实际编译方式的代码副本。 我使用“unifdef”实用程序得到了相当不错的结果,直到最近我还不知道。 但是,我很困惑为什么这么难以调用,我想知道我是否遗漏了什么。

考虑这个例子:

#ifdef A printf("A\n"); #endif #ifdef B printf("B\n"); #endif 

如果你使用“unifdef -DA junk.c”调用unifdef,你会得到:

  printf("A\n"); #ifdef B printf("B\n"); #endif 

因为你没有告诉unifdef B是未定义的,所以它没有把它拿出来。

我希望该实用程序的行为如此,当我说unifdef -DA时,我得到了:

  printf("A\n"); 

这将对应于C预处理器实际执行的操作:省略了未定义的任何分支。

要使用unifdef获得此行为,我似乎需要使用“unifdef -DA -UB junk.c”,明确告诉它B未定义。 虽然也许我错过了一种更简单的方式来调用它。

我编写了一个python脚本,从我正在使用的代码的Makefile中生成所需的-D和-U标志的长列表(通常每个例程80个)。 结果非常好。 但我想知道这样的剧本是否真的有必要。

另外一个实用程序(sunifdef?coan?)也可能已经内置了我想要的行为; 如果是的话,请提及。

coan实用程序使用-m标志执行您所需的操作:

 $ coan source -DA -m test.c printf("A\n"); 

从手册页:

 -m, --implicit Assume that any symbol that is not --define-ed is implicitly --undef-ed. 

您可以使用unifdef附带的unifdefall实用程序。 见http://dotat.at/prog/unifdef

如果我正确地理解了你的问题,你想在预处理器运行之后看到代码,对吗? 那么为什么不让预处理器运行它并查看它产生的输出? 只需使用编译时使用的完全相同的参数运行编译调用,但是将参数-E添加到它,这意味着“除了预处理之外什么都不做”。

 $ cat preproc.c #ifdef A printf("A\n"); #endif #ifdef B printf("B\n"); #endif $ gcc -E preproc.c # 1 "preproc.c" # 1 "" # 1 "" # 1 "preproc.c" $ gcc -E -DA preproc.c # 1 "preproc.c" # 1 "" # 1 "" # 1 "preproc.c" printf("A\n"); $ gcc -E -DB preproc.c # 1 "preproc.c" # 1 "" # 1 "" # 1 "preproc.c" printf("B\n"); $