当使用GCC时,鉴于我有时在发布中编译相同的库,有时在调试中,ABI是否保证兼容?
(使用相同的编译器时)
我有一个可执行文件和一些共享对象(一些依赖于其他对象),我希望能够交换发布/调试共享对象而无需重新编译所有内容 只有感兴趣的共享对象。
这是可能的,还是在某种情况下我可能会以这种方式得到一些未定义的行为? (假设我的代码是严格打包的,并在发布和调试中填充)
修改
我将详细说明我们所看到的问题。我们有intrusive_ptr
的自定义版本,在调试模式下,我们拥有自己的intrusive_ptr
,其中单个成员是boost::intrusive_ptr
,在发布中我们只是使用boost::intrusive_ptr
。我们intrusive_ptr
的API与boost::intrusive_ptr
的API相同,我们在课堂上没有任何虚拟功能。
我们看到的是这样的:
如果我们使用所有调试库或所有发布库都可以正常工作。如果我们将调试可执行文件与发布库混合使用,则intrusive_ptr
会发生内存泄漏,并且不会释放该对象。
我们的intrusive_ptr
和boost::intrusive_ptr
的大小在调试和发布中是相同的(我们的类不会在顶部添加任何大小开销)。
所以我想知道什么可能导致泄漏,ABI差异是唯一可以想到的事情。
想法?
答案 0 :(得分:0)
通常不会,因为版本和调试版本之间的通常区别只是使调试步进更好的选项。但是,如果在发布版本和调试版本之间以不同方式定义其他选项(例如整数大小,目标体系结构,??),则仍然可能出现意外行为,调用者参数可能与被调用者期望不匹配。异常安全性也存在问题,并且运行时链接器可能无法检查这些问题。
答案 1 :(得分:0)
我知道有几个编译器会为发布和调试生成不兼容的代码(尽管这些编译器很久以来一直被弃用)。除非用完全相同的标志编译,否则我不相信对象模块完全兼容。
这就是makefile(遵循GNU原则)和IDE之类的Eclipse将发布/调试/配置文件对象构建到不同目录中的原因。确保它们永远不会混淆。