如何避免cpp向宏参数添加空格

时间:2014-04-23 13:20:39

标签: c++ gcc macros

我的公司有1000个源文件,它们使用宏来指定包含路径。我无法改变它,它适用于当前的编译器。现在,我尝试用GCC(4.8.2或3.4.6)编译它,但它失败了。

基本上有一个像这样的宏:

#define COMP_INC(comp, file) <comp/include/file>

就像这样使用:

#include COMP_INC(posix, inttypes.h)

我的问题是GCC出于某种未知的原因将我的宏调用转换为:

#include <posix/include/ inttypes.h>

注意&#34; inttypes.h&#34 ;?之前的空格因此,找不到头文件。

为什么预处理器会插入空格?我可以避免吗?我只能更改宏,我无法更改使用它的源文件。

2 个答案:

答案 0 :(得分:3)

删除posixinttypes.h之间的空格(逗号后面)。问题消失了。

answer告诉我们为什么会这样:

  

来自C99标准:

     

表单

的预处理指令      

#define identifier replacement-list new-line

     

定义一个类似于对象的宏,它会导致宏名称的每个后续实例     替换为构成其余部分的预处理令牌的替换列表     指示。   

<小时/>   因此宏可以处理令牌,并且可以预期空白。

编辑:

根据此answer,您可以使用traditional-cpp标志来模仿不添加空格的旧行为。我不确定这会对你的构建产生什么影响,但你可以尝试一下:

  

只有很多较旧的预处理器没有插入额外的空间 - 请注意   原始条目是在20多年前的1988年之前提交的   1989年版的C标准已经标准化。你可以通过   -traditional-cpp标志到GCC预处理器,这导致它模仿老式C预处理器的行为,而不是   ISO C预处理器。

答案 1 :(得分:2)

如果您可以接受预定义所有可能的'comp'名称和'file'名称:

#define MAKE_INCLUDE(comp, file) <comp/include/file>

#define NAME_posix posix
#define NAME_inttypes inttypes

#define MAKE_NAME(x) NAME_##x

#define COMP_INC(comp, file) MAKE_INCLUDE(MAKE_NAME(comp), MAKE_NAME(file))

#include COMP_INC(posix, inttypes.h)

注意:像'。h'这样的后缀不能是宏的一部分。因此,像lib-1.0-A和lib-1.0-B这样的目录将无法区分(但这里可能没有问题)。