在线咨询
有事点这里
有事点这里
看不懂这篇文章?联系我们
("麦洛克菲"长期致力于内核安全的推广与普及,我们更专业!)
求职QQ群:223902435。讨论各种求职笔试面试问题
作者:admin 时间:2015-10-31
标题:命名重整(name mangling)
在C++里引入了重载这种机制,允许函数名相同,但函数参数类型和个数上不同。

重载是通过对函数进行“重整”(name mangling,又叫名字粉碎,命名修饰等)实现的。其实现的方法为:编译器根据函数的不同的参数表,对同名函数的名称做修饰,对于编译器而言,这些同名函数就成了不同的函数,他们的调用地址在编译期就绑定了。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。例如有这样一个函数:

int func(int x, int y);

int func(char x, int y);

经过编译后,函数变成为:

@func_int4int4

@func_char1int4

从此处可以看出,如果把返回值也做为一个可区别的特征话,即:

       int func(int x, int y);

       char func(int x, int y);

那么在做如下调用的时候:

       int a, b;

       func(a, b);

由于在语句中根本没包含返回值,就无法区别不同的重载函数了。

 

此外,如果在C++程序中要引用C语言编写的库和函数,必须加上extern “C”说明。这是为什么呢?

C语言中,由于没有重载机制,所以C编译器并不对函数进行重整,即不加相应的修饰符。如果不加extern “C”,那么C++就会对其中的函数进行重整,从而找不到相关的正确的函数体。只有加了之后,C++才不会对其进行重整,因此才能按照C的格式调用,使用对应的C代码。


重载函数应该在参数个数或参数类型上有所区别,否则编译器将无法确定调用哪一个重载版本,即使是返回类型不同,也无法区分。
例如:
int mul(int x,int y);
double mul(int x,int y);
虽然这两个函数的返回值类型不同,但是函数的参数个数和类型完全相同,编译器将无法区分这两个函数。 编译器通过函数名和其参数类型识别重载函数。为了保证类型安全的连接(type-safe linkage),编译器用参数个数和参数类型对每一个函数标识符进行专门编码,这个过程有时称为name mangling。类型安全的连接使得程序能够调用合适的重载函数并保证了参数传递的一致性。编译器能够检测到并报告连接错误。