ABI发布和调试之间的兼容性

时间:2016-05-31 14:19:19

标签: c++ gcc compilation shared-ptr abi

当使用GCC时,鉴于我有时在发布中编译相同的库,有时在调试中,ABI是否保证兼容?

(使用相同的编译器时)

我有一个可执行文件和一些共享对象(一些依赖于其他对象),我希望能够交换发布/调试共享对象而无需重新编译所有内容 只有感兴趣的共享对象。

这是可能的,还是在某种情况下我可能会以这种方式得到一些未定义的行为? (假设我的代码是严格打包的,并在发布和调试中填充)


修改

我将详细说明我们所看到的问题。我们有intrusive_ptr的自定义版本,在调试模式下,我们拥有自己的intrusive_ptr,其中单个成员是boost::intrusive_ptr,在发布中我们只是使用boost::intrusive_ptr。我们intrusive_ptr的API与boost::intrusive_ptr的API相同,我们在课堂上没有任何虚拟功能。
我们看到的是这样的:
如果我们使用所有调试库或所有发布库都可以正常工作。如果我们将调试可执行文件与发布库混合使用,则intrusive_ptr会发生内存泄漏,并且不会释放该对象。

我们的intrusive_ptrboost::intrusive_ptr的大小在调试和发布中是相同的(我们的类不会在顶部添加任何大小开销)。

所以我想知道什么可能导致泄漏,ABI差异是唯一可以想到的事情。

想法?

2 个答案:

答案 0 :(得分:0)

通常不会,因为版本和调试版本之间的通常区别只是使调试步进更好的选项。但是,如果在发布版本和调试版本之间以不同方式定义其他选项(例如整数大小,目标体系结构,??),则仍然可能出现意外行为,调用者参数可能与被调用者期望不匹配。异常安全性也存在问题,并且运行时链接器可能无法检查这些问题。

答案 1 :(得分:0)

我知道有几个编译器会为发布和调试生成不兼容的代码(尽管这些编译器很久以来一直被弃用)。除非用完全相同的标志编译,否则我不相信对象模块完全兼容。

这就是makefile(遵循GNU原则)和IDE之类的Eclipse将发布/调试/配置文件对象构建到不同目录中的原因。确保它们永远不会混淆。