CLL-符号修饰与函数签名

我们知道,在c++中,函数是可以重载的,也就是说函数名相同,但参数不同。那么编译器和链接器是怎样区分两个同名的函数的呢?由目标文件的三魂七魄(如果不清楚可以看看这边文章)可以知道,函数名和变量名都是符号(symbol),正是c++的符号修饰(name decoration)机制支持了这种特性。

在c中,现在gcc编译器,函数名的符号一般都是函数名本身,所以c没有函数重载这样的特性。

下面,通过一个实例来说明符号修饰机制

在这里插入图片描述

通过g++ -c test.cpp -o test.o编译后,再使用readelf -s test.o查看test.o的符号表信息。
在这里插入图片描述

可发现,所有的函数的符号修饰都是以"_Z"开头。

第17、18行的两个函数名分别为_Z4funci_Z4funcf;4 表示函数名的字符个数,i和f分别表示函数的形参的数据类型;

第32行的函数名为_ZN1A4funcEi,因为该函数是类A的函数,所以_Z后紧跟一个N,接着是类名的长度,本例中类名A只有一个字符,所以长度为1;对于在命名空间或类里面的函数,它的符号修饰是以E结尾,紧接着跟函数的形参数据类型。

也就是说,在namespace或class内部定义的函数,被修饰后的函数名是以N开头,以E结尾,中间的修饰名称由**[命名空间字符长度][命名空间名][类名字符长度][类名]函数名长度 函数名** 组成。

函数签名可以通过c++filt命令查看

函数签名(function signature)包含函数名、函数参数类型、所在类及命名空间的信息。
在这里插入图片描述