name mangling在wiki上的定义:它提供了在函数、结构体、类或其它的数据类型的名字中编码附加信息一种方法,用于从编译器中向链接器传递更多语义信息。
简单来说就是在编译阶段将函数名进行转换,加入域和参数信息,通过这种方式实现重载。
Name mangling的目的就是避免重复,原理就是:找到一种编码方法,使得
1)每一个名称经过转换后,要有唯一的名字;
2)这种编码必须简单,而且要可逆,就是能由全局名称很快的知道局部的名称
在g++下这种编码方式是:
1、所有编码后的符号都由_Z开头
2、如果有作用域符,则在_Z之后加上N
6、最后加上函数形参符号,int就是i,float就是f,有几个形参就写几个符号
linux可以用 c++filt 命令查看转换之前的函数声明
具体的转换表参考:http://hipercomer.blog.51cto.com/4415661/855223
举个栗子:
输入:
c++filt -n _ZN1N1C4funcEi
输出:
N::C::func(int)
输入:
c++filt -n _Z9test_funcRiPKcdSsf
输出:
test_func(int&, char const*, double, std::string, float)
简单来说就是在编译阶段将函数名进行转换,加入域和参数信息,通过这种方式实现重载。
Name mangling的目的就是避免重复,原理就是:找到一种编码方法,使得
1)每一个名称经过转换后,要有唯一的名字;
2)这种编码必须简单,而且要可逆,就是能由全局名称很快的知道局部的名称
在g++下这种编码方式是:
1、所有编码后的符号都由_Z开头
2、如果有作用域符,则在_Z之后加上N
3、接下来是命名空间名字长度+命名空间名字和类名长度+类名
4、函数名字长度+函数名字
5、如果有作用域符,则以E结尾6、最后加上函数形参符号,int就是i,float就是f,有几个形参就写几个符号
linux可以用 c++filt 命令查看转换之前的函数声明
具体的转换表参考:http://hipercomer.blog.51cto.com/4415661/855223
举个栗子:
输入:
c++filt -n _ZN1N1C4funcEi
输出:
N::C::func(int)
输入:
c++filt -n _Z9test_funcRiPKcdSsf
输出:
test_func(int&, char const*, double, std::string, float)

由于c语言和c++的name mangling方式是不同的,所以就会产生一个问题:如果在c语言中调用c++的函数,就会因为在链接时找不到函数而产生错误。解决的办法就是在用到的c++函数之前加上关键字extern "C",这样c++的函数就会按照c语言的name mangling方式,链接便能正确执行。
先定义两个简单的函数
double sum(double x,double y){
return double();
}
void foo(int lhs,int rhs){
}
- 1
- 2
- 3
- 4
- 5
- 6
g++ -c mangling.cc -o mangling.o
nm -a mangling.o
- 1
- 2
nm命令:显示可执行文件的符号信息 详见http://man.linuxde.net/nm
输出如下(省略了部分内容):
00000022 T __Z3fooii
00000000 T __Z3sumdd
参考:http://blog.sina.com.cn/s/blog_7e050dc80102wcbo.html