C++ ABI问题列表

45

我看到了很多关于C++没有像C那样的标准ABI的讨论。我很好奇,究竟有什么问题?目前,我想到的包括:

  1. 名称重整(Name mangling)
  2. 异常处理(Exception handling)
  3. RTTI

除了这些与C++相关的ABI问题外,还有其他问题吗?


4
Windows 和 Unix 中的 wchar_t 有点令人烦恼,但我不确定如何对其进行分类 :-) - Šimon Tóth
3
“不,这并不明显。请给出一个“C++库中的C部分函数”在Windows上“无法工作”的示例。” - Ben Voigt
3
你在说什么?Linux使用UTF-8字符串。 - Puppy
2
@BenVoigt,所以你认为fopen期望UTF-8字符串?这真是太棒了。这是链接:https://dev59.com/dlvUa4cB1Zd3GeqPuH0A 顺便说一下,我使用MSVC、Intel和GCC,因为我教授C和C++,所以需要知道这些主要编译器的功能如何。 - Šimon Tóth
3
让我们在聊天中继续这个讨论。链接为:http://chat.stackoverflow.com/rooms/3662/discussion-between-let-me-be-and-ben-voigt - Šimon Tóth
显示剩余13条评论
5个回答

43

脑海中浮现的:

C++ 特定内容:

  • 'this' 参数的位置。
  • 虚函数如何调用
    • 即是否使用 vtable 或其他方法
    • 实现这一过程所使用的结构体布局是什么。
  • 多个定义如何处理
    • 多个模板实例化
    • 未内联的内联函数。
  • 静态存储期对象
    • 如何处理创建(在全局范围内)
    • 如何处理函数局部创建(如何将其添加到析构器列表中)
    • 如何处理销毁(按创建的相反顺序销毁)
  • 您提到了异常。但也需要了解在 main() 之外如何处理异常
    • 即在 main() 之前或之后

通用内容:

  • 参数传递位置
  • 返回值位置
  • 成员对齐
  • 填充
  • 寄存器使用情况(哪些寄存器被保留,哪些是临时寄存器)
  • 基本类型的大小(例如 int)
  • 基本类型的格式(浮点数格式)

你列出的所有问题都已经被现有的C++ ABI(例如ARM ABI)所覆盖。唯一没有包含在现有ABI中的是C++标准库对象的布局,正如我在之前的回答中指出的那样。 - Lindydancer
没有真正的C++实现不使用虚表。 - curiousguy

24

在我的经验中,最大的问题是C++标准库。即使有ABI规定了类应该如何布局,不同的编译器也提供了不同的std::stringstd::vector等标准对象实现。

我并不是说无法对C++库对象的内部布局进行标准化,只是以前还没有这样做过。


3
在Visual Studio 2008中更改编译器选项就足以导致std::vector的不兼容布局。 - quant_dev
1
@Tux-D 我认为他的意思是,STL类型不是不透明的。 - Šimon Tóth
这不是我的理解方式。他暗示STL对象有不同的接口,这是不正确的。我非常同意改变任何编译器标志可能会导致不兼容的二进制对象。 - Martin York
3
他们确实具有不同的接口。当成员函数被内联时,接口包括私有对象的布局,而不仅仅是标准中定义的公共接口。许多实现细节未在标准中指定。以小字符串优化为例。 - Ben Voigt
1
@quant_dev: MSVC标准库的调试版本与常规版本不兼容。实际上,新的libc++的目标之一就是具有兼容的布局,无论使用何种编译度数(这需要外部存储信息)...您是否了解其他可能影响布局的情况? - Matthieu M.

10
我们最接近标准C++ ABI的东西是Itanium C++ ABI

  

本文档编写为通用规范,可供各种架构上的C++实现使用。但是,它确实包含了针对Itanium 64位ABI的处理器特定材料,被标识为这样的。

GCC文档解释了对该ABI的C++支持:
  

从GCC 3.2开始,GCC用于C++的二进制约定基于一种书面的、供应商中立的C++ ABI,该ABI旨在针对64位Itanium进行特定设计,但也包括适用于任何平台的通用规范。其他编译器供应商在一些平台上也实现了这个C++ ABI,尤其是GNU/Linux和BSD系统。

正如@Lindydancer所指出的,您还需要使用相同的C++标准库或运行时。

4
正如 @Lindydancer 所说,C++ 库在 Linux 上的二进制兼容性更多地与单一通用的 C++ 运行时库有关(由 g++ 提供),而不是与 ABI 有关。 - Ben Voigt
1
@BenVoigt,这是真的,也是你在API中看到许多指针用于传递向量或字符串内容的原因之一。现在,这些指针正在受到span、string_view等类似工具的竞争...你知道是否有努力使至少视图在不同的STL实现之间兼容吗? - Patrick Fromberg
@PatrickFromberg,是的,Herb Sutter在2014年提出了一个建议。http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4028.pdf - ysdx

5
任何语言的ABI标准都需要来自想要支持这种标准的平台。特别是C/C++等语言,由于许多原因(主要是使语言变得不够灵活和不够可移植),这些语言的标准实际上无法做到这一点。C确实没有定义的ABI,但许多平台都定义了(直接或间接的)。C ++之所以没有出现这种情况,是因为这种语言更加复杂,而且经常更改。然而,Herb Sutter有一个非常有趣的提议,关于如何让更多的平台创建标准的ABI,以及开发人员如何编写使用标准ABI的代码:https://isocpp.org/blog/2014/05/n4028。他指出了C ++通过extern "C"的方式链接到平台C ABI,但没有C ++ ABI的标准方式。我认为这个提案可以大大促进用C ++来定义接口而不是用C。

1
我看到了很多關於 C++ 沒有像 C 那樣的標準 ABI 的討論。標準的 C ABI 是什麼?C99 標準中的附錄 J 有 27 頁,除了未定義的行為(一些實現將某些 UB 定義為良好定義的行為)外,它還涵蓋了未指定的行為、實現定義的行為、區域特定的行為和常見擴展。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接