C++ name mangling

name mangling在wiki上的定义:它提供了在函数、结构体、类或其它的数据类型的名字中编码附加信息一种方法,用于从编译器中向链接器传递更多语义信息。
简单来说就是在编译阶段将函数名进行转换,加入域和参数信息,通过这种方式实现重载。


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

猜你喜欢

转载自blog.csdn.net/qq_33890670/article/details/80270355
今日推荐