为什么C函数不能被名称破坏?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

我最近接受了一次采访,有一个问题是extern "C"C ++代码中的用法。我回答说它是在C ++代码中使用C函数,因为C不使用名称修改。有人问我为什么C不使用名称修改,说实话我无法回答。

我明白,当C ++编译器编译函数时,它给函数提供了一个特殊的名称,主要是因为我们可以在编译时在C ++中重载具有相同名称的函数。在C中,函数的名称将保持不变,或者在_之前使用_。

我的查询是:允许C ++编译器破坏C函数还有什么不对?我会假定编译器给它们的名称并不重要。我们在C和C ++中以相同的方式调用函数。

提问于
用户回答回答于

这是上面回答的,但我会尝试将事情放到上下文中。

首先,C来了。因此,C所做的就是“默认”。它不会破坏名称,因为它不会。函数名称是一个函数名称。全球化是全球化的,依此类推。

然后C ++出现了。C ++希望能够使用与C相同的链接器,并能够与使用C编写的代码链接。但是C ++不能让C保持原样(或者缺少)。看看下面的例子:

int function(int a);
int function();

在C ++中,这些是不同的功能,具有不同的主体。如果它们都没有被破坏,则两者都将被称为“函数”(或“_function”),并且链接器将会抱怨重新定义符号。C ++解决方案是将参数类型转换为函数名称。所以,一个被调用_function_int,另一个被调用_function_void(不是实际的修改方案),并且避免了碰撞。

现在我们留下了一个问题。如果int function(int a)在C模块中定义了,并且我们仅仅是在C ++代码中使用它的头(即声明)并使用它,编译器将生成一条指令给链接器以导入_function_int。当函数被定义时,在C模块中,它没有被调用。它被称为_function。这会导致链接器错误。

为了避免这个错误,在函数的声明过程中,我们告诉编译器它是一个函数,它被设计成与C编译器链接或编译:

extern "C" int function(int a);

C ++编译器现在知道要导入_function而不是_function_int,而且一切都很好。

用户回答回答于

这并不是说他们“不能”,他们通常不是

如果你想在一个名为C的库中调用一个函数foo(int x, const char *y),那么让你的C ++编译器把它变成foo_I_cCP()(或者其他任何东西,只是在现场制定一个修改方案)是不好的,因为它可以。

该名称不会解析,该函数使用C语言,其名称不依赖于参数类型列表。所以C ++编译器必须知道这一点,并将该函数标记为C以避免进行修改。

请记住,所说的C函数可能位于你没有的源代码库中,你所拥有的只是预编译的二进制文件和头文件。所以你的C ++编译器不能做“它自己的东西”,毕竟它不能改变库中的内容。

扫码关注云+社区