C++ 中 extern “C” 的作用是什么?


extern “C” 关键字用于使 C++ 中的函数名具有 C 链接。在这种情况下,编译器不会对函数名进行修饰。让我们首先了解 C++ 中的名称修饰,然后讨论 extern “C” 关键字。

在 C++ 中,我们可以使用函数重载功能。使用此功能,我们可以创建同名的函数。唯一的区别是参数的类型和参数的数量。这里不考虑返回类型。现在问题来了,C++ 如何区分目标代码中的重载函数?

在目标代码中,它通过添加有关参数的信息来更改名称。这里应用的技术称为名称修饰。C++ 没有标准化的名称修饰技术。因此,不同的编译器使用不同的技术。

这是一个名称修饰的示例。重载函数命名为 func(),还有一个函数 my_function()。

示例

int func(int x) {
   return x*x;
}
double func(double x) {
   return x*x;
}
void my_function(void) {
   int x = func(2); //integer
   double y = func(2.58); //double
}

一些 C++ 编译器会将其更改如下:

示例

int __func_i(int x){
   return x*x;
}
double __func_d(double x){
   return x*x;
}
void __my_function_v(void){
   int x = __func_i(2); //integer
   double y = __func_d(2.58); //double
}

C 不支持函数重载,因此当我们在 C++ 中链接 C 代码时,我们必须确保符号的名称不会更改。以下 C++ 代码将生成错误。

示例

int printf(const char *format,...);
main() {
   printf("Hello World");
}

输出

undefined reference to `printf(char const*, ...)'
ld returned 1 exit status

出现此问题是因为编译器更改了 printf() 的名称。并且它找不到更新的 printf() 函数的定义。为了克服这个问题,我们必须在 C++ 中使用 extern “C”。当某些代码在此块内使用时,C++ 编译器确保函数名不会被修饰。因此名称不会更改。因此,上面的代码将如下所示以解决此问题。

示例

extern "C"{
   int printf(const char *format,...);
}
main() {
   printf("Hello World");
}

输出

Hello World

注意:这些代码块在不同的编译器中可能会产生不同的结果。

因此,extern “C” 基本上是一种链接规范。在每个编译器中,我们都必须使用此关键字来指定 C 链接。我们还必须记住,链接规范必须在命名空间范围内。extern “C” 忽略类成员。

更新于:2019年7月30日

2K+ 浏览量

启动您的职业生涯

通过完成课程获得认证

开始
广告