链接和名称修改如何工作?
让我们来看这个代码示例
//header
struct A { };
struct B { };
struct C { };
extern C c;
//code
A myfunc(B&b){ A a; return a; }
void myfunc(B&b, C&c){}
C c;
让我们从代码部分开始逐行执行此操作。 当编译器看到第一个 myfunc 方法时,它不关心 A 或 B,因为它的使用是内部的。每个 C++ 文件都会知道它接收什么、返回什么。尽管两个重载都需要有一个名称,但是如何选择名称以及链接器如何知道哪个名称意味着什么? 接下来是 C c;我曾经遇到过一个错误,链接器无法识别,因此允许我访问其他 C++ 文件中的 C。这是因为 cpp 不知道 c 是 extern,我必须在标头中将其标记为 extern,然后才能成功链接。现在我不确定类类型是否与链接器和变量 C 有任何关系。我不知道 RTTI 将如何参与,但我确实知道 C 需要对其他文件可见。
链接器如何工作以及名称修改等。
Lets take this code sample
//header
struct A { };
struct B { };
struct C { };
extern C c;
//code
A myfunc(B&b){ A a; return a; }
void myfunc(B&b, C&c){}
C c;
Lets do this line by line starting from the code section.
When the compiler sees the first myfunc method it does not care about A or B because its use is internal. Each c++ file will know what it takes in, what it returns. Although there needs to be a name for each of the two overload so how is that chosen and how does the linker know which means what?
Next is C c; I once had a bug were the linker wouldnt reconize thus allow me access to C in other C++ files. It was because that cpp didnt know c was extern and i had to mark it as extern in the header before i could link successfully. Now i am not sure if the class type has any involvement with the linker and the variable C. I dont know how RTTI will be involved but i do know C needs to be visible by other files.
How does the linker work and name mangling and such.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我们首先需要了解编译在哪里结束和链接从哪里开始。编译涉及获取编译单元(C 或 C++ 源文件)并将其转换为目标文件。简而言之,这涉及为每个函数生成机器代码片段以及所有函数和静态(全局)变量的符号表。占位符用于该编译单元外部的编译单元所需的任何符号。
然后,链接器负责加载所有目标文件并使用实际地址(或机器独立代码的偏移量)解析所有占位符符号。它被放置在操作系统的动态加载程序加载可执行文件时可以读取的各个部分中。
所以对于具体情况。为了避免链接期间出现错误,编译器要求您声明当前编译单元将使用的所有外部符号。对于全局变量,必须使用 extern 关键字,对于函数,这是可选的。
编译单元中定义的所有函数和全局变量都具有外部链接(即可以被其他编译单元引用),除非使用 static 关键字(或 C++ 中的未命名命名空间)进行声明。在C++中,vtable也会有一个链接所需的符号。
现在在 C++ 中,由于函数可以重载,因此参数也构成函数名称的一部分。由于机器代码只是地址和寄存器,因此需要将额外信息添加到符号表中的函数名称中。这些额外的参数信息以重整名称的形式出现,并确保链接器链接到重载函数的正确版本。
如果您确实对血腥细节感兴趣,请查看 ELF 文件格式 (PDF) 在 Linux 上广泛使用。 Windows 具有不同的格式,但原理应该是相同的。
Itanuim(和 ARM)平台上的名称修改可以在此处。
We first need to understand where compilation ends and linking begins. Compilation involves taking a compilation unit (a C or C++ source file) and turning it into an object file. Simplistically, this involves generating snippets of machine code for each function as well as a symbol table for all functions and static (global) variables. Placeholders are used for any symbols needed by the compilation unit that are external to the said compilation unit.
The linker is then responsible for loading all the object files and resolving all the place-holder symbols with real addresses (or offsets for machine independent code). This is placed into various sections that can be read by the operating system's dynamic loader when loading an executable.
So for the specifics. In order to avoid errors during linking, the compiler requires you to declare all external symbols that will be used by the current compilation unit. For global variables one must use the
extern
keyword, for functions this is optional.All functions and global variables defined in a compilation unit have external linkage (i.e., can be referenced by other compilation units) unless one declares that with the
static
keyword (or the unnamed namespace in C++). In C++, the vtable will also have a symbol needed for linkage.Now in C++, since functions can be overloaded, the parameters also form part of the function name. Since machine-code is just addresses and registers, extra information needs to be added to the function name in the symbols table. This extra parameter information comes in the form of a mangled name and ensures that the linker links to the correct version of an overloaded function.
If you really are interested in the gory details take a look at the ELF file format (PDF) used extensively on Linux. Windows has a different format but the principles can be expected to be the same.
Name mangling on the Itanuim (and ARM) platforms can be found here.
http://en.wikipedia.org/wiki/Name_mangling
http://en.wikipedia.org/wiki/Name_mangling