本文共 1146 字,大约阅读时间需要 3 分钟。
目录
C++支持函数重载。例如,可以有多个函数拥有相同的函数名和不同的参数。
C++编译器如何区分这些函数?依靠添加参数信息到函数名中。这个称为名称修饰。C++标准没有明确规定name mangling的具体规范,所以不同的编译器有不同的添加方法。例如下面的函数 f()
int f (void) { return 1; }int f (int) { return 0; }void g (void) { int i = f(), j = f(0); }
C++编译器可能会将上面的名称修饰如下:
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。//将文件保存为.cpp文件,并使用C++编译器进行编译int printf(const char* format, ...); int main(){ printf("hello world\n"); return 0;}
编译输出信息:
undefined reference to `printf(char const*, ...)' ld returned 1 exit status编译失败的原因很简单,printf的函数名称被C++编译器更改了,并且它没有找到修改后的对应函数。
解决方法是:在C++代码中使用extern "C"。当一些代码被extern "C"覆盖时,C++编译器能保证其中的函数名字不会被修饰更改。 将上述代码改为下面所示,这个程序会正常工作并且打印出"hello world"。//将文件保存为.cpp文件,并使用C++编译器进行编译extern "C"{ int printf(const char*format,...);}int main(){ printf("hello world\n"); return 0;}
输出结果:
hello world
因此, 所有C风格的头文件(stdio.h, string.h等),都使用了extern "C"的来声明。
#ifdef __cplusplus
extern "C" { #endif //声明此头文件 #ifdef __cplusplus } #endif转载地址:http://pmeji.baihongyu.com/