我最近接受了一次采访,其中一个问题是 extern "C"
在 C++ 代码中的用途。我回答说是在 C++ 代码中使用 C 函数,因为 C 不使用名称修饰。有人问我为什么 C 不使用名称修饰,老实说我无法回答。
我知道当 C++ 编译器编译函数时,它会给函数一个特殊的名称,主要是因为我们可以在 C++ 中重载必须在编译时解析的同名函数。在 C 中,函数的名称将保持不变,或者可能在其前面带有一个 _。
我的疑问是:允许 C++ 编译器也破坏 C 函数有什么问题?我会假设编译器给它们起什么名字并不重要。我们在 C 和 C++ 中以相同的方式调用函数。
原文由 Engineer999 发布,翻译遵循 CC BY-SA 4.0 许可协议
上面有点回答了,但我会试着把事情放在上下文中。
首先,C是第一位的。因此,C 所做的就是“默认”。它不会破坏名称,因为它不会。函数名是函数名。全局就是全局,以此类推。
然后 C++ 出现了。 C++ 希望能够使用与 C 相同的链接器,并且能够与用 C 编写的代码进行链接。但是 C++ 不能让 C 的“修改”(或缺少)保持原样。查看以下示例:
在 C++ 中,这些是不同的函数,具有不同的主体。如果它们都没有被破坏,则两者都将被称为“函数”(或“_function”),并且链接器将抱怨符号的重新定义。 C++ 解决方案是将参数类型转换为函数名称。所以,一个叫做
_function_int
而另一个叫做_function_void
(不是实际的修改方案)并且避免了冲突。现在我们面临一个问题。如果
int function(int a)
是在 C 模块中定义的,而我们只是在 C++ 代码中获取它的标头(即声明)并使用它,编译器将生成一条指令给链接器以导入_function_int
.当函数被定义时,在 C 模块中,它没有被调用。它被称为_function
。这将导致链接器错误。为避免该错误,在函数 声明 期间,我们告诉编译器它是一个旨在与 C 编译器链接或由 C 编译器编译的函数:
C++ 编译器现在知道导入
_function
而不是_function_int
,一切都很好。