编译
-
编译过程
首先,编译器会执行预处理,也就是所有以"#"开头的预处理语句。
->优化阶段->生成汇编并转换到机器语言->生成obj文件
其中每个cpp文件都是单独的编译单元,都是独自生成相对的obj文件
后期才通过linker进行相互的链接。 -
预处理相关
大致有#include:单纯的将头文件内的所有文本复制到所在的位置。
#define:单纯的文本替换。
#if:进行条件判断,若满足条件,则if所包含的文本有效,反之则无效。
预处理相关设置:
1 生成预处理后的文件,但不能生成obj
2 生成汇编代码文件
3 设置优化级数,使生成的obj、asm等文件不包含优化代码
优化等级与runtime check挂钩
链接
- 链接过程:
首先,要理解链接是将多个obj文件链接为一个exe文件,并解决在某个文件中引用另一个文件中的符号相关的问题。
链接时,linker首先决定各个obj文件在最终exe文件中的位置,然后访问所有obj文件的地址表,将其全部地址进行重定向,然后遍历所有obj文件中未解决的符号,生成未解决符号表,并在符号表中查找匹配的符号,将未解决符号表填补完成,最后对每个obj文件进行排序即完成。
-
链接方式:
1 静态链接:在链接时,就查找obj中缺失的目标函数,再去静态库中查找相应的obj对象,直接包含在程序内,运行时不用再次查询。但这里在库中查找的obj对象是一整个,也就是说即使只使用了它其中一个函数,还是会包含obj中其他所有的函数,导致内存大量浪费;且每次更新库,都需要将库重新编译并链接一遍。但优点在于运行时不用查询,运行速度快。
2 动态链接:在运行时,检测到未解决符号,再去查找包含相应符号的obj文件,并且一个obj只用加载一次,空间使用率高,且更新时不用再次编译链接。但运行速度比不上静态库。
下面是动态链接的过程:
假设现在有两个程序program1.o和program2.o,这两者共用同一个库lib.o,假设首先运行程序program1,系统首先加载program1.o,当系统发现program1.o中用到了lib.o,即program1.o依赖于lib.o,那么系统接着加载lib.o,如果program1.o和lib.o还依赖于其他目标文件,则依次全部加载到内存中。当program2运行时,同样的加载program2.o,然后发现program2.o依赖于lib.o,但是此时lib.o已经存在于内存中,这个时候就不再进行重新加载,而是将内存中已经存在的lib.o映射到program2的虚拟地址空间中,从而进行链接(这个链接过程和静态链接类似)形成可执行程序。 -
库相关
1 编写库:
①新建空项目
②编