name mangling跟函数重载紧密相关。mangling的目的就是为了给重载的函数不同的签名,因此调用函数的时候才好确认。
不同的编译器可能规则不一样。
举个例子。
原文件 main.cc:
/// @author zhaolu
/// @file main.cc
namespace zhao {
class test {
public:
void func();
};
};
void zhao::test::func() {}
void func(){}
void func(int){}
void func(int,int){}
void func(char){}
void func(zhao::test* pointer){}
输入编译命令,生成目标文件:
g++ -c main.cc -o main.o
使用nm命令可以列出目标文件的符号:
nm main.o
可以看到:
192:~ lurongming$ nm main.o
0000000000000050 T __Z4funcPN4zhao4testE
0000000000000040 T __Z4funcc
0000000000000020 T __Z4funci
0000000000000030 T __Z4funcii
0000000000000010 T __Z4funcv
0000000000000000 T __ZN4zhao4test4funcEv
分别对应文件中声明的:
void func(zhao::test*)
void func(char)
void func(int)
void func(int, int)
void func()
void zhao::test::func()
所以大致可以推出规则:
- 编码后的符号由__Z开头
- 如果有作用域符,则在_Z之后加上N
- 再是 [命名空间名字长度+命名空间名字+类名字长度+类名字+] 函数名称长度+函数名称
- 如果有作用域符,则以E结尾
- 最后加上函数形参符号,void是v,int是i,char是c,P代表指针,有几个形参就写几个符号
推荐一个linux下的工具,c++filt,可以将解析后的符号还原:
192:~ lurongming$ nm main.o | cut -d " " -f 3,3 | c++filt
func(zhao::test*)
func(char)
func(int)
func(int, int)
func()
zhao::test::func()