C++ Name Mangling

背景

如下 C++ 代码所示:

/* name mangling test cpp file `lib.cpp` */

#include <iostream>

int test_func(int i, double j) {
	return (int)(i*j);
}

int main() {
	std::cout << "testing" << std::endl;
	test_func(1, 2.0);
	return 0;
}

g++ 编译之后,通过 readelf 读取编译出的二进制符号表,发现了一个很奇怪的现象——函数名称发生变化,如下所示:

root@ubuntu-jammy:~# g++ -o lib lib.cpp
root@ubuntu-jammy:~# readelf -a lib | grep test_func
    21: 00000000000011a9    36 FUNC    GLOBAL DEFAULT   16 _Z9test_funcid

Name Mangling

上述现象其实是 C++ 编译器的行为,它按照一定的规则对函数名进行了重新矫正,这个行为有一个专业叫法:Name Mangling,Name Mangling 需要解决的本质问题是:解决名字唯一性的问题。

GCC Name Mangling

对于 C++ 的 Name Mangling 规则,C++ 标准并没有做具体的规定,但各个编译器平台形成了一些事实性的标准。比如GCC的一个简单规则:

A global object with class or namespace qualifiers is coded as
<public name> ::= _Z <qualified name>
where

<qualified name> ::= N[<simple name> ]E

<simple name> ::= <name length> <name>

就是一个类的成员函数可能会被Name Mangling编码为:_Z+N+长度+名字+E

Name De-mangling

GNU Binutils 工具集中提供了 Name De-Mangling 相关的工具:

1. nm -C xxx
2. objdump -C xxx
3. readelf -C xxx

References

  1. C++ 的 Name Mangling - 云+社区 - 腾讯云