编译器理论和实作
既是又不是。
- 从编译器理论理解,#include头文件"相当于"插入了头文件的代码,以供源代码引用(宏定义、函数声明、其他头文件引入等等),这仅仅是理论的效果。利用GCC -E或者MSVC /E或/P选项可以看到"插入"的效果。
- 从编译器实作角度,为了提高效率,编译器在编译源代码的时候并不会将#include头文件直接插入到当前编译的源代码,一则会产生代码插入,源代码所在的内存移动,二则不利于相同头文件的优化。主流编译器的做法是单独申请内存保存文件并记录#include行号以便处理完头文件后继续编译当前源代码。
引用大量头文件造成编译耗时灾难
- 如果你看过windows.h或者看过C/C++/ObjC大工程,尤其源代码开头一堆头文件,修改某一个base头文件造成大量源代码被编译,鉴于此,C++20引入modules减少头文件包含编译时间,虽然Java/C#/Python早就抛弃头文件采用import module.
- 预编译头文件以及头文件缓存都是头文件优化策略。
- VS .pch和GCC的.gch都属于预编译头文件,注意一般选择稳定不会被经常改动的头文件。
- 确认预编译头文件真的加速编译过程,在VS选项中可开启"生成计时"可查看编译过程各个工具消耗的时间。
- 生成计时: "工具" -> "选项" -> "项目和解决方案" -> "VC++项目设置" -> "生成计时"