【问题标题】:g++ always backward-compatible with "older" static libraries?g++ 总是向后兼容“旧”静态库?
【发布时间】:2013-04-24 11:01:05
【问题描述】:

我有一些静态库,但我不是其所有者,它们是用旧版本的 g++ 4.3.2 编译的(c++11/c++0x 未激活)。

当我使用 g++ 4.6(没有 c++11)编译我的代码并使用 g++ 4.6 将其与这些链接时 静态库,它链接很好,我似乎在运行时没有遇到任何问题(虽然没有测试一切)。 我倾向于认为前向兼容性是可以的。

现在我想用 gcc 4.8 和 c++11 编译我的代码,并且仍然将它与那些相同的、未重新编译的静态库链接。

g++ 中的 ABI 更改是否只是链接向前兼容性的问题,还是也可能出现向后兼容性问题?

【问题讨论】:

    标签: c++ g++ backwards-compatibility abi


    【解决方案1】:

    用于 C++98 代码的 G++ ABI 向后兼容,一直到 GCC 3.4

    因此,如果您使用 GCC 4.8 编译和链接您的最终可执行文件,您可以链接到使用 GCC 3.4 到 4.8(但不是更新版本)构建的对象和库

    C++11 ABI 与 C++98 ABI 相同,C++98 和 C++11 通用的标准库类型具有相同的定义,(忽略 GCC 4.7 .0 和 GCC 4.7.1,在使用 C++11 时在 std::pair 和 std::list 中存在 ABI 不兼容问题,已在 4.7.2 及更高版本中修复),因此您可以链接 C++ 98 和 C++11 代码一起(除非 C++11 代码是使用 GCC 4.7.0 或 4.7.1 构建的)

    然而一些 C++11 库类型还不稳定,并且会在不同版本之间发生变化,例如因为它们是在最终的 C++11 标准之前发布的,并且必须进行更改以匹配最终规则。所以混合使用 GCC 4.6 构建的 C++11 代码和使用 GCC 4.8 构建的 C++11 代码不一定安全

    对于您的情况,所有 C++11 代码都是使用 GCC 4.8 构建的,这没问题。如果您升级编译器,您应该使用较新的 GCC 重新构建所有 C++11 代码以确保安全。 (C++98/C++03代码不需要重新编译)

    【讨论】:

    • 注:我刚刚添加的最后两段,我一开始应该说清楚但匆忙,对不起
    • 感谢您的精确,乔纳森(哦,对了,来自 ACCU 2013 的 Johathan!解释了高质量的答案 :)
    • @juanchopanza,你在 c++98 和 c++11 模式下总是得到相同的类型。新数据成员是否存在不受语言模式的影响。当新成员出现时,有一个特殊属性会改变名称修饰,因此新的std::list 和旧的std::list 是不同的类型。我很快就会写出这方面的文档。 (注意,这只适用于 GCC 5,目前发布的版本没有 O(1) std::list::size())。
    • @juanchopanza,仅适用于 GCC 4.7.0 和 4.7.1,它们是唯一添加 _M_size 成员而不更改修饰的版本。
    • @juanchopanza,我现在更新了 wiki 页面以提供有关其他问题的最新信息
    【解决方案2】:

    C++11 标准的目标是保持向后兼容性,编译器供应商也是如此。只要库不使用任何“破坏”C++11 标准的东西,库格式本身就应该是相同的。

    有关 C++11 中引入的更改,请参阅 this。

    因此,假设您使用调用库的代码(包括标头),您应该没问题。

    【讨论】:

      猜你喜欢
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 2021-06-03
      • 1970-01-01
      • 2017-08-27
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多