📜  在C++中名称修饰和外部“ C”

📅  最后修改于: 2021-05-26 00:58:48             🧑  作者: Mango

C++支持函数重载,即,可以有多个具有相同名称和不同参数的函数。 C++编译器在生成目标代码时如何区分不同的功能-它通过添加有关自变量的信息来更改名称。这种将附加信息添加到函数名称的技术称为名称处理。 C++标准没有指定任何特殊的名称处理技术,因此不同的编译器可能会将不同的信息附加到函数名称中。

考虑以下函数f()的声明

int  f (void) { return 1; }
int  f (int)  { return 0; }
void g (void) { int i = f(), j = f(0); }

C++编译器可能会将上面的名称混为一谈(来源:Wiki)

int  __f_v (void) { return 1; }
int  __f_i (int)  { return 0; }
void __g_v (void) { int i = __f_v(), j = __f_i(0); }

从C++链接时如何处理C符号?
在C语言中,名称可能不会被修饰,因为C语言不支持函数重载。因此,当我们在C++中链接C代码时,如何确保不更改符号名称。例如,请参阅下面的使用C的printf()函数的C++程序。

// Save file as .cpp and use C++ compiler to compile it
int printf(const char *format,...);
  
int main()
{
    printf("GeeksforGeeks");
    return 0;
}

输出:

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

编译器错误的原因很简单, printf的名称已由C++编译器更改,并且找不到带有新名称的函数定义。

问题的解决方案是C++中的外部“ C”。当将某些代码放在extern“ C”块中时,C++编译器确保函数名称不被破坏-与C编译器一样,编译器将发出一个名称不变的二进制文件。

如果将上述程序更改为以下程序,则该程序可以正常工作并在控制台上打印“ GeeksforGeeks”。

// Save file as .cpp and use C++ compiler to compile it
extern "C"
{
    int printf(const char *format,...);
}
  
int main()
{
    printf("GeeksforGeeks");
    return 0;
}

输出:

GeeksforGeeks

因此,所有C样式头文件(stdio.h,字符串.h,..等)在extern“ C”块中都有其声明。

#ifdef __cplusplus 
extern "C" {
#endif
    /* Declarations of this file */
#ifdef __cplusplus
}
#endif

以下是上面讨论的要点
1.由于C++支持函数重载,因此必须在函数名称中添加其他信息(称为名称重整),以避免二进制代码中的冲突。
2.由于C不支持函数重载,因此不能在C中更改函数名称。为避免链接问题,C++支持外部“ C”块。 C++编译器确保未更改外部“ C”块内的名称。

要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”