24

预编译的头文件似乎可以在大型项目中节省大量时间,但也似乎是一个有一些陷阱的麻烦事。

使用预编译头文件的优缺点是什么,特别是与在 Gnu/gcc/Linux 环境中使用它们有关?

4

6 回答 6

10

预编译头文件的唯一潜在好处是,如果您的构建速度太慢,预编译头文件可能会加快它们的速度。潜在的缺点:

  • 更多 Makefile 依赖项以确保正确;如果他们错了,你会快速构建错误的东西。不好。

  • 原则上,并非每个标头都可以预编译。(考虑在#include 之前放置一些#define。)那么gcc 究竟在哪些情况下是正确的?您有多想信任这个前沿功能。

如果您的构建速度足够快,则没有理由使用预编译标头。如果你的构建太慢,我会考虑

  • 购买更快的硬件,这比工资便宜

  • 使用 AT&T nmakeccache之类的工具(Dirk 是正确的),两者都使用可信赖的技术来避免重新编译。

于 2009-08-27T21:11:50.263 回答
8

我无法与 GNU/gcc/linux 交谈,但我已经处理了 vs2005 中的预编译头文件:

优点:

  • 当你有很多模块包含的大头文件时,可以节省编译时间。
  • 适用于很少更改的标题(例如来自第三方)。

缺点:

  • 如果将它们用于变化很大的标头,则会增加编译时间。
  • 可以进行繁琐的设置和维护。
  • 如果您不强制编译预编译的标头,则在某些情况下显然会忽略对标头的更改。
于 2009-08-27T20:56:41.060 回答
5

gcc、g++、gfortran的ccache缓存前端对我来说非常有用。正如其网站所说

ccache 是一个编译器缓存。它充当 C/C++ 编译器的缓存预处理器,使用 -E 编译器开关和哈希来检测何时可以从缓存中满足编译。这通常会导致普通编译的速度提高 5 到 10 倍。

在 Debian / Ubuntu 上,只需执行 ' apt-get install ccache' 并在其中创建软链接,例如,/usr/local/bin名称为gcc, g++, gfortran, c++, ... 指向/usr/bin/ccache.

[编辑]为了更明确地回应一些早期的评论:这通过缓存更大的编译步骤块来提供基本上预编译的头文件和源代码。所以它采用了一种类似于预编译头的思路,并将其进一步继承。加速可能是巨大的——正如网站所说,是 5 到 10 倍。

于 2009-08-27T20:54:44.340 回答
4

对于纯 C,我会避免预编译头文件。正如您所说,它们可能会导致问题,并且与常规编译相比,预处理时间非常短。

对于 C++,预编译的头文件可能会节省大量时间,因为 C++ 头文件通常包含大型模板代码,其编译成本很高。我没有使用它们的实际经验,因此我建议您衡量您在项目中节省了多少编译。为此,使用预编译的头文件编译整个项目一次,然后删除单个目标文件,并测量重新编译该文件需要多长时间。

于 2009-08-27T20:57:42.680 回答
4

GNU gcc 文档讨论了预编译头文件可能存在的缺陷。

于 2009-08-27T21:33:22.653 回答
0

我在一个 Qt 项目中使用 PCH,它使用 cmake 作为构建系统,它节省了大量时间。我抓住了一些 PCH cmake 脚本,它们需要一些调整,因为它们很旧,但通常比我预期的更容易设置。我必须补充一点,我不是 cmake 专家。

我现在包含了 Qt 的很大一部分(QtCore、QtGui、QtOpenGL)和一些稳定的头文件。

优点:

  • 对于 Qt 类,不需要前向声明,当然也不需要包含。
  • 快速地。
  • 易于设置。

缺点:

  • 您不能在标头中包含 PCH 包含。这不是什么大问题,除了你使用 Qt 并让构建系统单独翻译 moc 文件,这恰好是我的配置。在这种情况下,您需要在您的标头中#include qt 标头,因为 mocs 是从标头中分类的。解决方案是在标头中的#include 周围放置额外的包含保护。
于 2009-08-27T21:14:40.647 回答