【问题标题】:Precompiled Headers in Header Files头文件中的预编译头文件
【发布时间】:2012-07-09 07:59:44
【问题描述】:

我今天第一次遇到了预编译的头文件……永远改变了我的生活。我不敢相信编译我的 C++ 代码会这么快。现在完全有道理了..

无论如何,让我感到困惑的一件事是,从我目前所读到的内容来看,预编译的头文件只应该添加到源文件中(cpp?)。

在 Visual Studio 中,项目属性->C/C++->高级下有一个选项可以“强制包含文件”。我将该编译器选项设置为 stdafx.h

这样做之后..我不再需要包含我添加到我的 stdafx.h 的标题,即使在我的头文件中(源文件应该自动包含 stdafx.h )。这是预期的行为吗?

我在头文件/源文件之间的区别中找不到明确的地方。

如果确实如此.. 很好,但我担心这是 VC++ 让您侥幸逃脱但会在 GCC 中中断的另一件事。是的..它需要便携;至少在 GCC 和 VC++ 之间。

【问题讨论】:

  • 好吧,如果您希望您的项目也可以在 gcc 上运行,那么您最好远离“强制包含文件”选项。 Boilerplate 就是让你的源代码文件中的第一个#include 成为预编译的头文件。
  • @Hans,等效的 gcc 功能是使用 -include 命令行选项在每个文件的开头包含 stdafx.h

标签: c++ visual-studio visual-c++ gcc precompiled-headers


【解决方案1】:

StdAfx.h 真的应该只包含在源文件中,而不是头文件中。我建议您在每个 cpp 中首先 #include "StdAfx.h" 并且不要使用“强制包含文件”选项。这就是我对跨平台项目的处理方式。作为记录,我实际上并没有在 GCC 中使用预编译的头文件,我只是正常构建它并且效果很好。

对于一些背景。编译器只查看源文件(例如,*.cpp、*.c 等),因此当它编译它们时,它必须包含每个头文件并编译在头文件中找到的任何代码。预编译头选项允许编译所有代码(即 StdAfx.h 中的全局包含代码),这样您就不必一直这样做。这就是 StdAfx.cpp 的用途。编译器使用 StdAfx.h 中包含的所有代码编译 StdAfx.cpp 一次,而不必每次构建时都这样做。

因此,由于您将 StdAfx.h 作为第一项包含在每个源文件中,因此将其包含在任何标题中都是没有意义的,因为它们将包含在 StdAfx.h 之后,因此可以访问所有StdAfx.h 中的代码。此外,您还可以在其他项目中使用这些标头,而不必担心 StdAfx.h 周围存在或包含错误的标头。

【讨论】:

  • 我的问题是 VC++ 会自动将这些添加到标题中吗?使用未包含的类型(但在 stdafx.h 中)时,我没有收到任何错误。非常奇怪。
  • 不,强制包含选项将文件添加到每个源/cpp 文件的第一行。包含工作的方式是将要包含的文件的内容放入源文件中#include 的位置。使用 force include 选项可以使每个 CPP 文件的顶部都包含 StdAfx.h 的内容,然后是所有头文件和源代码的内容(以文件中的任何顺序)。因此,效果是,在您的 StdAfx.h 中定义的所有内容都将在该项目的标题中可用。编译器只查看源文件而不是头文件。
  • 哦,我明白了。这很有意义。谢谢你的解释。
【解决方案2】:

是的,这是预期的行为。 Project Properties->C/C++->Advanced to "Force Include File"设置控制Visual C++ compiler option /FI:

这个选项和用double指定文件的效果一样 每个文件第一行的#include 指令中的引号 源文件

因此,它使您无需手动包含 stdafx.h。

虽然,您可以将预编译的头文件与 GCC 和其他编译器一起使用 Visual C++ 的快捷方式行为不能跨其他编译器移植。因此,请查看How to handle stdafx.h in cross-platform code?,那里讨论了便携式解决方案的想法。

长话短说,在您的 .cpp 源文件中手动包含 stdafx.h 并且您应该也可以使用 GCC(假设您将为 GCC 配置您的构建以使用预编译头文件)。

【讨论】:

  • 向 .h 和 .cpp 文件添加广告?
  • 如果它只添加到 .cpp 文件中,为什么 VC++ 可以在我的头文件中减速这些类型而不包含它们?
  • @irwinb 您为 Visual C++ 和 GCC 将公共头文件添加到 stdafx.h。然后在 .cpp 文件中包含 stdafx.h。但是,如果您只使用 VC++,那么您可以使用 /FI 选项指定 stdafx.h,请求编译器自动为您包含此标头。
【解决方案3】:

不要使用“强制包含文件”设置 (/FI),因为它会破坏编辑并继续! (而且 MS 似乎不想解决这个问题)

https://connect.microsoft.com/VisualStudio/feedback/details/668339/vs-2010-sp1-c-edit-and-continue-fails-with-fi

https://connect.microsoft.com/VisualStudio/feedback/details/342441/visual-studio-2005-force-includes-breaks-edit-and-continue-with-pre-compiled-headers

#include "stdafx.h" 只能作为源文件中的第一个非注释行找到,而不是在头文件中。

【讨论】:

  • MS Connect 已退役,编辑并继续中的许多错误已针对 VS2019 进行了修复,不确定这一点。
猜你喜欢
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
  • 2015-01-03
  • 2015-01-05
  • 2012-09-08
  • 2011-02-25
相关资源
最近更新 更多