C / C++ / 奇思妙想 · 2024年 3月 10日 0

C语言#include头文件真的是插入代码吗?

36 次浏览

编译器理论和实作

既是又不是。

  • 从编译器理论理解,#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++项目设置” -> “生成计时”