C++ 如果我们有一个包含所有代码的单一文件项目,我们可以不使用链接器吗?

C++ 如果我们有一个包含所有代码的单一文件项目,我们可以不使用链接器吗?,c++,c,embedded,C++,C,Embedded,链接器问题: 如果我有档案。如果c完全没有包含,我们还需要一个链接器吗?虽然链接器之所以这样命名是因为它将多个对象文件链接在一起,但它还执行其他功能。它可能解析编译器留下的不完整地址。它以可执行文件格式生成程序,系统的程序加载器可以读取和加载该格式的程序,并且该格式可能不同于对象模块的格式。具体取决于操作系统和构建工具 此外,为了在一个源文件中有一个完整的程序,你不仅要提供C和C++所熟悉的代码>主< /COD>程序,还要提供程序的真正开始,程序加载程序开始执行的入口点,并且你必须为程序中使用的

链接器问题


如果我有档案。如果c完全没有包含,我们还需要一个链接器吗?

虽然链接器之所以这样命名是因为它将多个对象文件链接在一起,但它还执行其他功能。它可能解析编译器留下的不完整地址。它以可执行文件格式生成程序,系统的程序加载器可以读取和加载该格式的程序,并且该格式可能不同于对象模块的格式。具体取决于操作系统和构建工具


此外,为了在一个源文件中有一个完整的程序,你不仅要提供C和C++所熟悉的<>代码>主< /COD>程序,还要提供程序的真正开始,程序加载程序开始执行的入口点,并且你必须为程序中使用的所有函数提供实现。例如,通过特殊陷阱或系统调用指令调用系统服务以读取和写入数据。

是。链接器不仅仅是链接文件。有关详细信息,请查看此资源:


信不信由你,默认情况下可以引用多个库。因此,即使您不包含资源,编译器也可能必须在内部链接或引用翻译单元之外的内容。编译器还“消除”了冗余和其他注意事项。

您可以创建一个没有典型C启动代码的项目,在这种情况下,您甚至可能没有
main()
。但是,您仍然需要一个链接器,因为链接器为给定的体系结构创建所需的可执行文件格式

它还将设置入口点,实际执行从这里开始。 因此,您可以省略标准库,创建一个二进制文件,它完全没有任何C函数,但是您仍然需要链接器来实际创建一个可运行的二进制文件


编译器生成的对象文件格式与可执行文件格式大不相同,因为它只提供链接器所需的所有信息。

尽管链接器的名称正确地称为“链接器/定位器”。它执行两个功能:1)链接目标代码,2)确定数据和代码元素在内存中的位置

编译器外的目标代码没有“定位”,即使它没有未解析的链接

即使您有最简单的有效代码:

int main(){ return 0; }

在没有包含的情况下,链接器通常会隐式链接C运行时启动,这是在运行
main()
之前执行所有必要操作所必需的。这可能很少。在一些目标上,比如armcortex-M,只要不假设静态初始化或完全的库支持,实际上可以直接从重置向量运行C代码。因此,完全用C编写重置代码是可能的,但是您可能仍然需要代码来使用重置处理程序(您的C启动函数)和初始堆栈指针初始化向量表。在CordTym M上,可以使用内嵌汇编程序完成,但这是相当繁琐和不必要的,而且不会放弃链接器。< /P>是的,除非你打算重新在C和C++库中重新实现每个类、模板和函数。您通常需要链接到运行时库以进行输入和输出。需要链接器。对象文件格式不是ELF/EXE/where。链接器负责创建适当的可执行格式。是。在“编译然后链接”构建链中,编译器通常输出一个对象文件,该文件不是可执行格式。即使源文件不依赖任何头文件,也需要链接器将目标文件转换为可执行格式。唯一的区别是链接器可以将多个对象文件和库中的函数链接在一起(例如,将调用函数的每个点链接到被调用函数的起点)为了生成一个可执行文件,我就这样做了:如果我制作了一个文件.c,其中包括1-主函数2-,每个函数调用的主体3-最终将导致主函数的启动代码4-所有必须包含的,我不知道的,我仍然需要链接器来完成将文件.obj传输到的工作这个问题和这个答案让我想起了一篇关于直接加载和执行对象文件的博客文章。tl;dr:这是可能的,但是你必须手动完成很多事情,而不是依赖于加载程序。@AliHamdy,我的这篇博文并没有说到点子上,因为
parseObject
的存在表明链接器是不可避免的。将链接器的作业转换为自定义对象解析器只是混淆了这一点。