【问题标题】:When do i want to turn off "precompiled header" in visual studio?我什么时候想在 Visual Studio 中关闭“预编译头”?
【发布时间】:2014-01-20 15:15:13
【问题描述】:

首先我想说的是,我阅读了有关预编译头文件的信息,并且我知道这是一种优化,可以节省我在每次构建时一遍又一遍地编译头文件的时间。

我正在阅读 boost 的文档,我在他们说的说明中看到:

在 Configuration Properties > C/C++ > Precompiled Headers 中,将 Use Precompiled Header (/Yu) 更改为 Not Using Precompiled Headers

然后他们解释它:

使用带有预编译头文件的 Boost 没有问题; 这些说明只是避免了预编译的标头,因为它需要对示例中使用的源代码进行特定于 Visual Studio 的更改。

  1. 谁能解释一下我用粗体标记的句子?他们在谈论哪些视觉工作室特定的变化? (这里是我正在阅读的文档的链接:http://www.boost.org/doc/libs/1_55_0/more/getting_started/windows.html#pch
  2. 为什么以及何时要关闭预编译头文件?
  3. 预编译头选项中的“创建”和“使用”有什么区别。

【问题讨论】:

  • 嗯,你需要包含预编译的头文件。
  • 这是他们说样本不遵循统一的 use-this-lead-in-header-for-pch-generation 模型的口头禅的方式。 IOW,他们的 samples 对 PCH 不友好,但如果配置正确,您仍然可以在 your 项目中使用带有 boost 的 pch。
  • @user2485710:“需要”?不,当然不是。你需要你的豪车吗?你去年放的那个假期?你说你“需要”一个 IDE 来“让一切正常工作”,而不是让事情变得更容易。
  • 这些东西在技术上不是操作编译器的 pch 功能所必需的。
  • 你仍然需要你的 IDE 的支持几乎读作必需

标签: c++ boost precompiled-headers


【解决方案1】:

最初是评论,但我不妨发布它。注意:这是特定于 VC++ 的:

  1. 粗体句是他们表示样本不遵循统一的 use-this-lead-in-header-for-pch-generation 模型的口头禅的方式。 IOW,他们的示例对 PCH 不友好,但如果配置正确,您仍然可以在项目中使用带有 boost 的 pch。

  2. 出于各种原因,您会关闭它们。一些源模块,尤其是来自第 3 方的源模块,不遵循 PCH 模型,即在一开始就包含“the”pch-through-header。他们的示例就是这样的代码(因此建议为他们的示例关闭它们)。有时源文件仅针对该文件而不是项目中的所有文件需要不同的预处理器配置;为这些文件禁用 PCH 的另一个原因。

  3. 您通常使用 a 源/标头对来生成“the One”;预编译的标题图像。该头文件通常包括:

    1. 项目使用的任何系统标准库头文件
    2. 第三方 SDK 标头
    3. 您的 项目中几乎所有其他未在积极开发中的东西。

标记为 Create 的单个源文件通常包含一行代码:#include "YourHeaderFile.h",其中YourHeaderFile.h 是您用上面列表中的内容填充的标题。通过标头YourHeaderFile.h 将其标记为“创建”告诉VC,它是在编译其他源文件时通过该标头重建PCH 所需的文件。所有其他源文件都被标记为 Use(PCH 关闭的除外),并且应该包含相同的#include "TheHeaderFile.h" 作为它们的第一行代码。

简而言之(难以置信),<boost> 告诉您他们的示例没有像上面描述的那样设置,因此您应该在构建它们时关闭 PCH

【讨论】:

    【解决方案2】:

    当您使用预编译的头文件时,您需要执行以下操作:

    #include <foo>
    #include <bar>
    #include <baz>
    
    #pragma hdrstop
    
    // other code here
    

    #pragma之前的所有内容都进入预编译的标头。它之后的一切都取决于预编译的头文件。使预编译头工作的 VC++ 特定“魔法”是 #pragma

    故事远不止这些。为了使预编译的头文件正常工作,您希望在每个源文件中以完全相同的顺序包含完全相同的一组头文件。

    这会导致(通常)创建一个包含所有其他常见标头并在其末尾有 #pragma hdrstop 的标头,然后将其包含在所有其他源文件中。

    然后,当编译器做它的事情时,有两个阶段:首先你需要创建一个预编译的头文件。这意味着使用一个开关运行编译器。编译器只查看#pragma hdrstop之前的内容,构建符号表(等等)并将数据放入.pch 文件中。

    然后是使用预编译头文件进行构建的阶段。在这个阶段,编译器会简单地忽略文件中直到#pragma hdrstop 的所有内容。当它到达时,它会从.pch 文件中读取编译器的内部状态,然后开始编译那个单独的文件。

    这意味着每个源文件通常都包含许多它实际上并不需要的标头。反过来,这意味着如果您使用预编译的头文件,那么最终的编译速度要比您根本没有做任何事情来支持预编译的头文件要慢得多。

    换句话说,虽然唯一绝对需要的部分是#pragma hdrstop,它是相当无害的,但需要更多的文件重组才能从中受益——如果您使用任何不支持预编译头文件的东西(VC++ 的做法与此相同),那么这些更改可能会对编译时间造成严重影响。

    【讨论】:

    • 除了在 Visual C++ 中,它与 #include 指令之一中使用的文件名匹配,而不是 #pragma hdrstop
    【解决方案3】:

    当每个 cpp 源文件上都有预编译头文件时,必须以 #include "stdafx.h" 开头

    因此,如果您不想编辑所有 boost 源文件,可以将其关闭。

    当预编译头文件位于 stdafx.cpp 时“创建”预编译头文件。所有其他文件“使用”预编译头文件。

    【讨论】:

    • 它不必被称为“stdafx.h”(这是一个设置),也不必是#included,有一个高级选项可以强制包含它。
    猜你喜欢
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 2012-07-28
    • 2021-07-30
    • 2019-05-28
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    相关资源
    最近更新 更多