为什么名称错位不规范

时间:2012-04-12 16:42:24

标签: c++ name-mangling

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

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

[1]所有以extern "C"出口函数的人都会说话。

2 个答案:

答案 0 :(得分:22)

该标准未涉及实施细节。有许多, 许多依赖于实施的东西,它们阻止了 从一起工作的课程:如何布置课程, vtable等的结构。一般来说,编译器会改变 如果他们改变其中任何一个,就会命名。这是故意的,因为它 防止无法通过链接工作的代码。

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

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

答案 1 :(得分:15)

标准实际上并不需要名称修改。就此而言,标准不要求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系统通常在寄存器中而不是在堆栈中传递它们的参数?