预编译头文件中应该放什么?(MSVC)

40

最佳的预编译头文件候选者是什么?我可以把STL和Boost头文件放在那里,即使它们有模板?这样做会减少编译时间吗? 另外,有哪些最佳IDE设置可以减少编译时间?


3
我不想使用PCH。原因是(1)我喜欢在cpp文件中第一个包含的头文件就是它所对应的头文件,这样你就知道头文件能够编译。(2)我的经验表明,使用pch进行依赖检查并不完全可靠,这导致在非常大的项目中增量构建变得不可靠。我认为,总的来说,不使用pch更有效,并且可以享受可靠的增量构建的好处。这可能在最新的Visual Studio版本中已经不再适用了——我的经验还不足以判断。 - Permaquid
4个回答

51
简而言之:STL和Boost头文件确实应该放在预编译的头文件中,即使这些头文件定义了模板类。
编译器会将头文件文本解析为二进制格式,并优化为编译器所需的形式。即使模板类在其他.cpp文件编译时被实例化,它们也将从预编译头文件中实例化,这对于编译器来说要快得多。
但是,您不应该在预编译头文件中包含项目中经常更改的文件,即使每个.CPP文件都包含这些文件。这是因为生成预编译头文件可能需要很长时间,因为boost、stl和windows库非常庞大。如果一个开发人员触及StringDefs.h,那么每个开发人员都必须等待整个预编译头文件重新编译。如果StringDefs.h省略在预编译头文件中,而是与每个.CPP文件一起解析,速度会更快。

这是个很好的观点 - 包括经常变动的文件会减慢构建速度。 - Andy
5
每个.cpp文件只能有一个预编译头文件,但是在您的项目中可以有多个预编译头。 - Brian R. Bondy
1
你不仅需要等待PCH重新编译,还要等每个使用它的文件。 - Andreas Haferburg
你有任何证据来支持模板确实会得到改进的说法吗?例如,性能分析结果或编译器文档链接? - bacar
如果一个开发人员触及了 StringDefs.h,那么每个开发人员都必须等待整个预编译头文件重新编译,我认为这是预期行为,如果 StringDefs.h 被轻微修改的话。 - zwcloud

6

除了Andrew Shepherd的答案之外,还有一个补充。对于那些与您的项目无关且很少更改的头文件,请使用预编译头文件。如果您一直在更改当前项目中的头文件,则预编译它们可能不值得。


4

我写了一篇关于减少编译时间的技巧的文章。其中,可以找到有关预编译头和其应用的帖子这里。它还有一个关于最佳实践的部分,你可能会觉得很有趣。包含处理它的 CMake 脚本。


这是一篇不错的文章。 - spellmansamnesty

-1

将大多数项目中的 .cpp 文件都会包含的任何内容放入预编译头文件中。实际上,这适用于任何头文件。这样可以让编译器仅解析一次这些文件,然后在同一项目中的所有 .cpp 文件中重复使用该信息。


2
我不同意,并在我的回复中写了一个额外的部分来解释为什么。 - Andrew Shepherd
预编译头文件中绝不能包含项目本地的头文件。 - Tom
我曾经在一个遵循这个错误建议的项目上进行了大量工作,它非常低效 - 每次编译时,所有内容都会为任何更改而重新编译。 - Permaquid
11
预编译头文件不应包含项目本地头文件。为什么呢?如果这些本地头文件是稳定的,从来不会更改,并且在整个应用程序中都被包含了,那为什么不能将它们放入预编译头文件中呢? - 0xC0DEFACE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接