在观看某乎视频【7】【Cherno C++】【中字】C++链接器是如何工作的时看到一个比较新奇的事情,以下是我自己写的一个:
#include <iostream>
using namespace std;
void Fun();
int main() {
Fun();
return 0;
}
首先我们看到,这几行代码只包含了输入输出流头文件,接下来是名称空间,再接下来是Fun()
的声明,最后是main()
函数。
再看看项目目录是什么样组织的:
左边是文件结构,只有两个.cpp
文件;
中间是Fun.cpp
,Fun()
是在这个文件中被定义;
右边是main.cpp
,Fun()
在这个文件中被声明和调用。
可以猜猜看这个程序可以正常运行吗?
答案是:完全可以。
输出结果:
我们知道,如果在调用某个函数时,如果函数定义不在当前文件夹,那应该要把函数所在的头文件包含进来。但是在这里,我们只包含了iostream
这个头文件,并没有包含任何其他的头文件,那运行main函数时,它怎么知道Fun()
的定义是什么呢?
这就涉及到编译和链接的内容了。使用vs工具时,一般只点开始执行(不调试)程序就能跑起来,但是从代码从文本文件到加载到内存中让CPU执行的过程发生了什么事情我们都不知道,或者说这个过程需要做些什么事情,vs都帮我们做好了。而这部分工作就是编译和链接。
点编译文件时,文件就会从.cpp
的文本文件转换编译为.obj
格式目标文件,执行程序之前,程序就会把这些.obj文件中的内容拼接起来。对于上面程序能运行,我的理解是,编译之后再链接时,程序会把Fun.obj
中关于Fun()
的定义部分链接到main.obj
中的第5行,使得程序可以运行。
稍微具体一点的说明可以看一下文章开头的视频链接。