我的公司有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 ;?之前的空格因此,找不到头文件。
为什么预处理器会插入空格?我可以避免吗?我只能更改宏,我无法更改使用它的源文件。
答案 0 :(得分:3)
删除posix
和inttypes.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这样的目录将无法区分(但这里可能没有问题)。