
预编译头文件(Precompiled Header,简称 PCH)是 C++ 编译器提供的一种优化机制,用来加速重复包含大量头文件(尤其是标准库、第三方库等稳定不变的头)的编译过程。
为什么需要 PCH?
大型项目中,每个 .cpp 文件常以 #include iostream>、#include
怎么用 PCH?(以常见工具链为例)
关键不是“写一个头”,而是“约定+配置”:
- 选一个头文件作为 PCH 入口:比如 StdAfx.h(MSVC 习惯)或 pch.h(跨平台常用),里面集中包含所有项目中高频、不变、不常修改的头
- 先单独编译它生成 PCH 文件:例如 MSVC 中设置该文件属性为“创建预编译头”;Clang/GCC 用 -x c++-header 参数
- 其余 .cpp 文件开头必须第一行是 #include "pch.h"(MSVC 要求严格;Clang/GCC 可配 -include pch.h 绕过位置限制)
- 编译器自动识别并复用已生成的 PCH:只要头内容或编译选项(如宏定义、语言标准)没变,就跳过重编译
哪些头适合放进 PCH?
目标是“高频率引入 + 极少改动”:
立即学习“C++免费学习笔记(深入)”;
- 标准库头:
stream> 、、 、 等 - 项目级公共头:Common.h、Platform.h(不含条件编译或频繁变更内容)
- 稳定的第三方 SDK 头(如 Qt 的
,前提是版本固定)
避免放入:#define DEBUG 这类易变宏的头、模板实现头(如 impl.h)、依赖当前 .cpp 特定上下文的头——否则 PCH 失效或引发 ODR 错误。
注意事项和常见坑
PCH 加速明显,但配置不当反而拖慢或出错:
- 修改 PCH 内容后,所有依赖它的 .cpp 都要重新编译(因为 PCH 文件时间戳变了)
- 不同编译单元若用不同宏开关(如 #define _CRT_SECURE_NO_WARNINGS)包含同一 PCH,可能导致不一致行为
- MSVC 要求 PCH 必须是第一个 #include,且前面不能有任何代码/注释(包括空行)
- CMake 中启用 PCH 需显式调用 target_precompile_headers()(CMake 3.16+),旧版本需手动配置编译选项
基本上就这些。PCH 不复杂但容易忽略细节,用对了,大型项目的全量编译时间能减少 20%~50%。










