【问题标题】:Why is name mangling not standardized为什么名称修饰不标准化
【发布时间】:2012-04-25 01:25:16
【问题描述】:

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

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

[1] 所有将函数导出为 extern "C" 的人都在说话。

【问题讨论】:

  • 标准化名称修改只会给您一种错误的安全感,因为您还必须标准化 ABI 以获得适当的互操作性。而且 C++ 标准委员会不太可能涉足 ABI 标准化业务。
  • +1 @Raymond - 在互操作性问题上对自己撒谎是个坏消息。这就像依赖未定义的行为一样。当然,您认为它有效,但实际上无效。
  • 诚然,就 C++ ABI 达成一致要比 C 困难得多。稍微 OT:这个问题中究竟有什么不适合 3 人的 SO?毕竟,正如已经显示的那样,显然存在一个很好的独特答案。
  • ABI 是与实现相关的,即它强烈依赖于机器。在不同的机器上,你最终会得到不同的 ABI,这不是 C++ 作为一门语言的范畴。它更多地属于汇编程序的领域。这就是 C++ 委员会没有对 ABI 进行标准化的原因。但它通常由实现者和机器设计者(如 Intel 等)标准化。下面是 Intel Itanium 用于 C++ 的 x86 ABI 的非常详细的描述:sourcery.mentor.com/public/cxx-abi
  • 与所有“为什么 XXX 不标准化”的答案相同:太难了,不够用,微软想阻止兼容性等 :-)

标签: c++ name-mangling


【解决方案1】:

该标准不涉及实施细节。有许多, 许多取决于实施的事情,并阻止 一起工作的程序:课程的布置方式, vtable 等的结构。一般来说,编译器会改变 如果他们更改其中任何一个,则名称修改。这是故意的,因为它 防止无法链接的代码。

给定平台可以定义 C++ ABI;所有编译器 坚持它将使用兼容的实现,并具有 通用名称修饰。这是平台供应商的问题, 然而;无论出于何种原因,很少有供应商定义了 C++ ABI。

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

【讨论】:

  • 应该补充一点,即使 mangling 是标准化的,extern "C" 还是需要的,因为 C 不做任何 mangling 并且 C++ 必须支持重载函数,所以符号在任何地方都是不同的案例。
  • @JanHudec 实际上并没有很好地定义extern "C" 的含义。例如,在没有 C 编译器的平台上是什么意思?然而,在实践中,大多数(如果不是所有)平台都定义了 C ABI,而extern "C" 意味着坚持这一点。在这里,名称修改也不是唯一的问题。我曾在 C 和 C++ 之间将顺序变量推入堆栈的平台上工作过。 (此外,我使用的大多数 C 编译器都使用了名称。只是比 C++ 简单得多。)
【解决方案2】:

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

在它可以依赖的广泛 ABI 之前,GCC actually went out of its way to use a different name mangling scheme 比它的竞争对手:

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

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

名称修改也比许多程序员意识到的要复杂。例如,标准将如何指定acceptable calling conventions for all platforms that C++ could run on?是否应该要求 RISC 系统支持 x86 stdcall,即使 RISC 系统通常在寄存器而不是堆栈中传递参数?

【讨论】:

  • 实际上,自 C++20 起,二进制补码已被标准化为整数,因此您可能应该从答案中编辑该示例。
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 2010-11-21
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多