2012-04-12 60 views
24

我只是想知道为什么名称修改从未标准化的C++标准。很显然,使用不同的名称修改算法会影响互操作性[1],我认为没有实现定义的好处。为什么名称修改不规范

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

[1]所有那些输出功能为extern "C"的人发言。

+11

标准化的名称修改只会给您一种错误的安全感,因为您还必须对ABI进行标准化才能获得适当的互操作性。而C++标准委员会不太可能参与ABI标准化业务。 – 2012-04-12 16:46:12

+3

+1 @Raymond - 向你自己讲述互操作性是个坏消息。这就像依靠未定义的行为。当然,你认为它有效,但它确实没有。 – 2012-04-12 16:47:04

+0

没错,同意C++ ABI会比C更难。稍微OT:这个问题究竟是什么被3人认为不适合SO?毕竟,很明显存在一个明确的答案,正如已经显示的那样。 – Voo 2012-04-12 17:00:53

回答

19

该标准没有涉及实施细节。有很多东西取决于实现,并且阻止程序共同工作:如何布置类,vtable的 结构等等。一般来说,编译器会更改名称如果它们改变改变任何这些。这是有意的,因为它可以防止链接不起作用的代码。

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

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

+2

应该补充的是,即使mangling被标准化,无论如何都需要extern”C“,因为C不会做任何改动,而且C++必须支持重载函数,所以在任何情况下符号都是不同的。 – 2012-04-12 16:53:39

+3

@JanHudec它实际上并没有很好地定义'extern“C”'的含义。例如,在没有C编译器的平台上,这意味着什么?然而,实际上,即使不是所有平台都定义了C ABI,“extern”C也意味着坚持这一点。而且,在这里,名称不是唯一的问题;我曾经在C和C++之间将顺序变量推入堆栈的平台上有所不同。 (另外,我使用的大多数C编译器都会使用mangle的名字,只是比C++简单得多。) – 2012-04-12 17:00:31

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系统通常将它们的参数传递到寄存器而不是栈中,RISC系统是否需要支持x86 stdcall