请解释 C++ ABI
Please explain the C++ ABI
不修复 C++ 的一些问题的常见解释是它会破坏 ABI 并需要重新编译,但另一方面我遇到这样的语句:
Honestly, this is true for pretty much all C++ non-POD types, not just exceptions. It is possible to use C++ objects across library boundaries but generally only so long as all of the code is compiled and linked using the same tools and standard libraries. This is why, for example, there are boost binaries for all of the major versions of MSVC.
(来自 this SO answer)
那么C++有稳定的ABI吗?
如果可以,我能否在同一平台上混合和匹配使用不同工具集编译的可执行文件和库(例如 VC++ 和 Windows 上的 GCC)?如果没有,有什么办法吗?
更重要的是,如果 C++ 中没有稳定的 ABI,为什么人们如此担心破坏它?
C++ 目前还没有 ABI 标准。他们试图将其纳入标准;您可以阅读下面的详细解释:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2028r0.pdf
虽然 C++ 标准没有规定任何 ABI,但一些实际的实现会努力保持工具链版本之间的 ABI 兼容性。例如。使用 GCC 4.x,可以使用链接到旧版本 libstdc++
的库,该程序由具有较新 libstdc++
的较新工具链编译的程序。库期望的旧版本符号由较新的 libstdc++.so
提供,并且 C++ 标准库中定义的 类 的布局相同。
但是当 C++11 向 std::string
和 std::list
引入新要求时,如果不更改这些 [=29= 的布局,则无法在 libstdc++
中实现这些要求].这意味着,如果您不将 _GLIBCXX_USE_CXX11_ABI=0
kludge 与 GCC 5 及更高版本一起使用,您将无法通过例如std::string
GCC4 编译库和 GCC5 编译程序之间的对象。所以ABI坏了。
一些 C++ 实现不会那么努力地拥有兼容的 ABI:例如MSVC++ 不提供主要编译器版本之间的这种兼容性(参见 this question),因此必须提供不同版本的库才能与不同版本的 MSVC++ 一起使用。
因此,一般来说,即使是同一工具链,您也不能混合搭配使用不同版本编译的库和可执行文件。
不修复 C++ 的一些问题的常见解释是它会破坏 ABI 并需要重新编译,但另一方面我遇到这样的语句:
Honestly, this is true for pretty much all C++ non-POD types, not just exceptions. It is possible to use C++ objects across library boundaries but generally only so long as all of the code is compiled and linked using the same tools and standard libraries. This is why, for example, there are boost binaries for all of the major versions of MSVC.
(来自 this SO answer)
那么C++有稳定的ABI吗?
如果可以,我能否在同一平台上混合和匹配使用不同工具集编译的可执行文件和库(例如 VC++ 和 Windows 上的 GCC)?如果没有,有什么办法吗?
更重要的是,如果 C++ 中没有稳定的 ABI,为什么人们如此担心破坏它?
C++ 目前还没有 ABI 标准。他们试图将其纳入标准;您可以阅读下面的详细解释:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2028r0.pdf
虽然 C++ 标准没有规定任何 ABI,但一些实际的实现会努力保持工具链版本之间的 ABI 兼容性。例如。使用 GCC 4.x,可以使用链接到旧版本 libstdc++
的库,该程序由具有较新 libstdc++
的较新工具链编译的程序。库期望的旧版本符号由较新的 libstdc++.so
提供,并且 C++ 标准库中定义的 类 的布局相同。
但是当 C++11 向 std::string
和 std::list
引入新要求时,如果不更改这些 [=29= 的布局,则无法在 libstdc++
中实现这些要求].这意味着,如果您不将 _GLIBCXX_USE_CXX11_ABI=0
kludge 与 GCC 5 及更高版本一起使用,您将无法通过例如std::string
GCC4 编译库和 GCC5 编译程序之间的对象。所以ABI坏了。
一些 C++ 实现不会那么努力地拥有兼容的 ABI:例如MSVC++ 不提供主要编译器版本之间的这种兼容性(参见 this question),因此必须提供不同版本的库才能与不同版本的 MSVC++ 一起使用。
因此,一般来说,即使是同一工具链,您也不能混合搭配使用不同版本编译的库和可执行文件。