为什么名称重整不规范

Why is name mangling not standardized

本文关键字:为什么      更新时间:2023-10-16

我只是想知道为什么名称重整从未被C++标准标准化。显然,使用不同的名称重整算法会损害互操作性[1],而且我认为将其定义在实现上没有任何优势。

也就是说,与调用约定或原语大小相反,机器本身并不关心甚至不知道函数是如何调用的。那么为什么它没有标准化,为什么它仍然没有标准化呢?编译器过去在版本之间更改了规则。

[1] 所有这些将功能导出为extern "C"的人都说明了一切。

该标准不涉及实现细节。 有很多,许多事情依赖于实现,并且阻止了一起工作的程序:课程是如何布局的,vtable的结构等。 通常,编译器会更改如果他们更改其中任何一个,则名称重整。 这是故意的,因为它防止链接无法正常工作的代码。

给定的平台可以定义一个C++ ABI;所有编译器遵守它将使用兼容的实现,并具有俗名重音。 这是平台供应商的问题,然而;无论出于何种原因,很少有供应商定义了C++ ABI。

extern "C"工作的原因是因为几乎所有平台都定义了C ABI。

该标准实际上不需要名称重整。 就此而言,该标准不需要IEEE浮点数或任何其他东西。

在有一个可以依赖的广泛 ABI 之前,GCC 实际上不遗余力地使用与其竞争对手不同的名称重塑方案:

G++ 不像其他C++编译器那样执行名称重整。这意味着使用一个编译器编译的目标文件不能与另一个编译器一起使用。

这种效果是有意为之的,以保护您免受更微妙的问题。编译器在C++实现的许多内部细节方面有所不同,包括:类实例的布局方式、多重继承的实现方式以及如何处理虚函数调用。如果名称编码相同,您的程序将链接到其他编译器提供的库 - 但程序在运行时会崩溃。然后在链接时而不是运行时检测不兼容的库。

名称重整也比许多程序员意识到的要复杂得多。 例如,标准如何为C++可以运行的所有平台指定可接受的调用约定? 是否应该要求RISC系统支持x86 stdcall即使RISC系统通常在寄存器中而不是堆栈上传递其参数?