ZHCU820Y September 2004 – June 2021
每个外部可见的标识符都会分配一个用于目标文件的唯一符号名,即所谓的链接名。该名称由编译器根据一种算法分配,该算法取决于符号的名称、类型和源语言。该算法可能会向标识符添加前缀(通常是下划线),并且可能会改编 名称。
用户定义的符号(使用 C 代码和汇编代码)存储在同一个命名空间中,这意味着需要确保 C 标识符不与汇编代码标识符相冲突。标识符可能与汇编关键字(例如寄存器名称)相冲突;在这种情况下,编译器会自动使用转义序列来防止冲突。编译器使用双平行线对标识符进行转义,这指示汇编器不要将标识符视为关键字。需要确保 C 标识符不与用户定义的汇编代码标识符相冲突。
名称改编会对函数链接名中函数参数的类型进行编码,仅发生在未声明为 extern "C" 的 C++ 函数中。改编会实现函数重载、运算符重载和类型安全链接。请注意,函数的返回值未在改编后的名称中编码,因为无法根据返回值重载 C++ 函数。
例如,名为 func 的函数的 C++ 链接名的一般形式如下:
func__F parmcodes
其中,parmcodes 是对 func 参数类型进行编码的字母序列。
对于这个简单的 C++ 源文件:
int foo(int i){ } //global C++ function
生成的汇编代码如下:
foo__Fi
foo 的链接名是 foo__Fi,表示 foo 是一个仅接受整数类型参数的函数。为了帮助检查和调试,提供了一个名称还原实用程序,可将名称还原为 C++ 源代码中的名称。请参阅Topic Link Label9,了解详情。
改编算法遵循 Itanium C++ ABI (http://www.codesourcery.com/cxx-abi/abi.html) 中的描述。
int foo(int i) { }
将改编为 _Z3fooi