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

if we had a single file project that contained all the code can we not use the linker?

链接器问题:

如果我有一个文件。 c 根本没有包含,我们还需要一个 linker 吗?

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

此外,要在一个源文件中包含一个完整的程序,您不仅必须提供您从 C 和 C++ 中熟悉的 main 例程,而且还必须提供程序的真正开始,入口点程序加载器开始执行,您必须为您在程序中使用的所有功能提供实现,例如通过特殊陷阱调用系统服务或系统调用指令来读取和写入数据。

是的。 linker 做的不仅仅是 link 文件。查看此资源以获取更多信息:https://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Compiler/Linker#:~:text=The%20linker%20is%20a%20program,translation%20unit%20have%20external%20linkage.

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

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

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

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

尽管它的名字是 linker 正确的是“linker/locater”。它执行两个功能 - 1) linking 目标代码,2) 确定数据和代码元素在内存中的位置。

编译器输出的目标代码没有被“定位”,即使它没有未解析的 links。

此外,即使您拥有最简单的有效代码:

int main(){ return 0; }

with no includes, linker 通常会隐式地 link C 运行time start-up, 这需要在 运行宁 main() 之前做所有必要的事情。那可能很少。在某些目标上,例如 ARM Cortex-M,只要您不假设静态初始化或完整的库支持,您实际上可以直接从重置向量 运行 C 代码。因此可以完全用 C 语言编写重置代码,但您可能仍需要代码来使用重置处理程序(您的 C 启动函数)和初始堆栈指针来初始化向量 table。在 Cortex-M 上,也许可以使用内联汇编器来完成,但这非常麻烦且不必要,并且不会放弃 linker.