由于预处理器指令导致的共享对象不匹配

时间:2012-01-17 06:34:32

标签: c++ gcc

我正在使用qcc在'IBM Rational Rhapsody 7.5'中构建一个共享对象项目,而qcc又使用gcc。

当在具有完全相同构建环境的两台不同机器上构建相同代码时,观察到二进制不匹配。

在一些试验和错误方法之后,我发现不匹配是由于用于条件执行代码的pre-processsor指令(使用#ifdef)。当删除预处理器指令并且项目构建在不同的机器上时这两个二进制文件完全匹配。

是否有任何理由'为什么会出现这种不匹配?

预处理器指令是否在目标文件中添加了机器相关参数,因此它们会反映在可执行文件中,从而导致不匹配? 请指导我。

1 个答案:

答案 0 :(得分:0)

预处理程序指令#ifdef执行条件编译。这是否会导致二元不兼容取决于#ifdef与相应#endif之间的内容。例如,以下显然根本没有任何效果:

#ifdef FOO
#endif

无论是否定义FOO,编译的代码看起来都完全相同。

但是,以下情况肯定会导致不兼容:

#ifdef HAS_FOO_STRUCT
typedef foo foo_type;
#else
struct foo_type {};
#endif

void bar(foo_type);

在这里,如果定义了HAS_FOO_STRUCT,bar(foo_type)实际上是bar(foo),并且会被严重损坏。另一方面,如果未定义HAS_FOO_STRUCTfoo_type实际上是此名称的一种类型,因此bar(foo_type)将具有该名称。这将存在二进制不兼容。

请注意,定义的宏的差异可能来自几个不同的地方。首先,不同的编译器版本可以定义不同的宏(或将宏定义为不同的值)。例如,有一些宏标识您正在编译的系统类型,并标识编译器版本。宏中的差异也可能来自系统头文件,它们可能具有不同的#define s。此外,构建系统可以定义宏,指示是否在系统上找到某些事物(例如预安装的库)。

请注意,您看到的二进制不兼容性可能是有意的,以防止遇到更微妙的二进制不兼容性,这在编译时没有显示,但在某些条件下会导致奇怪的错误。