链接和名称管理如何工作? [英] How does linkage and name mangling work?

查看:137
本文介绍了链接和名称管理如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们来获取这段代码示例

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;

让我们从代码段开始逐行。
当编译器看到第一个myfunc方法时,它不关心A或B,因为它的使用是内部的。每个c ++文件将知道它需要什么,它返回什么。虽然需要为每个两个重载一个名称,那么如何选择它,以及链接器如何知道哪个是什么意思?
接下来是C c;我曾经有一个错误,链接器不会重新聚合,因此允许我访问C在其他C ++文件。这是因为cpp不知道c是extern,我不得不将其标记为extern在标题中,我可以链接成功之前。现在我不知道类类型是否有任何参与链接器和变量C.我不知道如何RTTI将涉及,但我知道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.

链接器如何工作和命名mangling等。

How does the linker work and name mangling and such.

推荐答案

我们首先需要了解编译结束并开始链接。编译涉及获取编译单元(C或C ++源文件)并将其转换为目标文件。简单地说,这涉及为每个函数生成机器码的片断以及用于所有函数和静态(全局)变量的符号表。占位符用于编译单元在所述编译单元外部所需的任何符号。

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 resolve 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.

因此,具体细节。为了避免链接期间的错误,编译器需要声明当前编译单元将使用的所有外部符号。对于全局变量,必须使用 extern 关键字,对于这是可选的函数。

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.

在函数中定义的所有函数和全局变量都有外部链接(即可以被其他编译单元引用),除非用 static 关键字(或C ++中未命名的命名空间)。在C ++中,vtable还将有一个用于链接的符号。

All functions and global variables defined in a function have external linkage (ie 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.

现在在C ++中,由于函数可以被重载,这些参数也构成函数名的一部分。由于机器代码只是地址和寄存器,因此需要将额外的信息添加到符号表中的函数名称。这个额外的参数信息以修改名称的形式出现,并确保链接器链接到重载函数的正确版本。

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.

如果你真的对血腥的细节感兴趣,看看 ELF文件格式(PDF)。 Windows具有不同的格式,但原则可以预期是相同的。
可以在找到Itanuim(和ARM)平台上的名称调整这里

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.

这篇关于链接和名称管理如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆