【问题标题】:Shared Object Mismatch due to Preprocessor directive由于预处理器指令导致共享对象不匹配
【发布时间】:2012-01-17 06:34:32
【问题描述】:

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

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

经过一些试验和错误方法后,我观察到不匹配是由于用于有条件执行代码的预处理器指令(使用#ifdef)造成的。当预处理器指令被删除并且项目在不同的机器上构建时.这两个二进制文件完全匹配。

“为什么会发生这种不匹配”是否有任何原因?

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

【问题讨论】:

  • #ifdef 块内的代码是什么?在不知道的情况下,不可能说出问题所在。
  • 指令测试什么符号?
  • 两个环境之间肯定存在一些差异,可能是 CPU 类型、操作系统版本、内核版本、编译器版本或其他。你应该仔细检查一下。

标签: c++ gcc


【解决方案1】:

预处理器指令#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_STRUCT 没有定义,foo_type 确实是该名称的一种类型,因此bar(foo_type) 将具有该名称。这将存在二进制不兼容。

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

请注意,您看到的二进制不兼容很可能是故意的,以防止遇到更微妙的二进制不兼容,这种不兼容不会在编译时出现,但会在某些情况下导致奇怪的错误。

【讨论】:

  • 我正在尝试在 2 台具有完全相同构建环境(编译器版本等)的不同机器上构建相同的共享库(即相同的代码)。在两台机器上,将被编译的代码将是相同的,因为预处理器指令是在两台机器上定义的。如果在两台机器上都删除了指令的定义,则二进制文件完全匹配。即使编译的代码在两台机器上都相同,预处理器指令如何造成不匹配?
  • 这些机器是否也安装了完全相同的库?特别是对于有问题的共享库使用的库?
  • 是的,使用的库也一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2017-02-07
  • 1970-01-01
相关资源
最近更新 更多