gcc/Linux 使用的 C++ ABI/重整方案称为Itanium C++ ABI。Mangling 是第 5.1 节。
除了这个之外,还有多少其他常用的 C++ ABI 和重整方案?他们叫什么?
(例如,我假设 MSVC 和 Windows 有自己的一个?它叫什么?它在某处有记录吗?)
我将尝试总结(非常短的)邮件列表线程,并添加一些我自己在编译器方面的回忆(使用 EDG 的前端,因为它是大约 2005 年\xe2\x80\x932010 ):
\n许多 POSIX 平台都使用 Itanium C++ ABI。存在多种实现(例如,GNU 有一种,LLVM/Clang 有一种),并且它们自然会略有不同 \xe2\x80\x94 ,这既是因为错误,也是因为它们可能或多或少关心特定于供应商的极端情况。
\nint (^)(int)为U13block_pointerFiiE. Clang 和 GCC 都无法c++filt将其返回到类似int (^)(int). 而且GCC根本不支持块类型。Microsoft 使用 Microsoft C++ ABI。
\n最初的 Cfront 使用了您也可以称之为“Cfront C++ ABI”的内容,记录在ARM的 \xc2\xa77.2c中。Edison Design Group 的类似 Cfront 的前端使用的默认重整是 Cfront C++ ABI 的直系后代。
\n我确信还存在其他破坏方案,特别是如果你看看 20 世纪 90 年代的寒武纪大爆发,并且不坚持认为破坏一定会一直持续到 2020 年代……
\n这是这三个损坏的具体示例:
\nnamespace Hello { class World; }\nstruct Class {\n explicit Class(int);\n int func(const double&, Hello::World*) const;\n};\nRun Code Online (Sandbox Code Playgroud)\n安腾损坏:_ZN5ClassC1Ei, _ZNK5Class4funcERKdPN5Hello5WorldE.
微软修改:??0Class@@QEAA@H@Z,?func@Class@@QEBAHAEBNPEAVWorld@Hello@@@Z
Cfront 修改:__ct__5ClassFi, func__5ClassFRCdPQ25Hello5World. (ARM没有解释如何区分完整对象构造函数和用于虚拟基的子对象构造函数;您必须查看实际的实现,例如 EDG 的实现,才能弄清楚这一点。)
与名称修改相反,还有更多 ABI 决策需要做出:
\n异常处理是否使用表(正如指定的 Itanium ABI 那样),或者每个函数周围的 setjmp/longjmp 序言/结尾代码?
\nvtable 是否包含简单的函数指针(当需要转换为虚拟基时指向“thunk”),或者使用更复杂的模式(消除对“thunk”代码的需要,但使每个虚拟调用站点复杂化)在 Cfront 中并显示在ARM \xc2\xa710.8c中?
\n尺寸和布局是怎样的int (Widget::*)()?指向非虚函数的指针可以很容易地与 相同大小int (*)(),但如果Widget包含虚函数怎么办?Itanium ABI表示 int (Widget::*)()应该是两个指针的大小。如果我理解正确的话,Microsoft ABI 也只是使用 thunk 来实现此目的,并且int (Widget::*)()是单个函数指针的大小(可能指向 thunk)。
类前面、类末尾、中间的虚拟基 \xe2\x80\x94 的结构布局是什么(如图所示,尽管可能是偶然的,在ARM \xc2\xa710.5c中)?它们在运行时的偏移量存储在哪里?\xe2\x80\x94 每次我们将未知动态类型的指针投射到其虚拟基数之一时,我们都需要知道这些偏移量。Microsoft ABI 同时使用“vfptr”(虚拟函数表)和“vbptr”(虚拟基址偏移表),而 Itanium ABI 仅使用 vfptr(他们称之为“vptr”),并且虚拟基偏移量存储在vtable之前的内存中。
\nstruct E { virtual ~E(); }; struct F : virtual E {};\xe2\x80\x94 Microsoft 制造sizeof(F)==16,而 Itanium 和 Cfront 仅制造8。我们如何做内联函数和模板:预链接器?COMDAT 部分(如果是的话,我们如何命名它们)?
\n可能还有更多我没有想到的旋钮。
\n| 归档时间: |
|
| 查看次数: |
264 次 |
| 最近记录: |