Visual Studio 强制在项目的所有编译单元中包含预编译头文件?

问题描述 投票:0回答:3

当编译器编译源文件(例如

*.cpp
)文件时,它会创建目标文件(例如
*.o
),以便稍后它将链接到其他
.o
.so
(对于Windows为
.lib
文件)文件和将构成可执行文件。

现在,对于类似的情况,每次创建一些 .pch 文件时不编译头文件,以便链接器随后将其链接。

现在,如果在 Visula Studio 项目的范围内定义了预编译头,那么为什么 Visual Studio 会抱怨头文件未包含在 .cpp 文件中的错误(例如

**fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?**
)。

总结一下,我的问题如下:

  1. 为什么在每个.cpp文件中项目的预编译头是 有必要吗?
  2. 每个编译单元中存在预编译头的要求如何优化编译过程?换句话说,这个要求有什么好处呢? (可以由用户决定在哪里包含,在哪里不包含!)
  3. 如果预编译头包含在.cpp文件中,它只使用.pch文件中的2%,那么剩下的98%将被添加到相应的.o文件中?
c++ visual-studio-2008 linker precompiled-headers
3个回答
12
投票

为什么每个.cpp文件中都需要项目的预编译头?

因为是你要求的。 如果您不想使用它,则需要更改 .cpp 文件的选项。 右键单击它,属性,C/C++,预编译头,“创建/使用”=“不使用预编译头”。 默认设置为“使用”。 这样做没有什么意义。

各个编译单元中的预编译头是如何优化编译过程的?

无需解析#includes。 当您

#include <windows.h>
时特别有用。 在包含数百个 .cpp 文件的大型项目中,节省的时间约为数秒,总计可达数分钟。 这是迄今为止加速编译器最便宜的方法,并且不会降低生成代码的质量。

那么剩下的98%会被添加到相应的.o文件中去吗?

当然不是。


4
投票
  1. 实际上没有必要在每个编译单元中都包含预编译头。 您可以在该文件的 C/C++->预编译头属性部分中为单个文件设置“不使用预编译头”设置。 但这是一项艰巨的工作,而且我从来不知道有人在生产代码中做到这一点。
  2. 优化在于,预编译头仅构建一次,并且整个 shebang 被所有编译单元重用,而无需重新编译/重新包含(某种程度)。 如果您有一组被多次包含的文件,这可以节省大量编译时间。 另请参阅预编译头文件的维护和提供
  3. 不,您不会获得多余的文件内容,就像静态链接时不会获得的一样。

2
投票
  1. 我猜你的问题意味着“为什么编译器不能假设这个头文件总是存在的,如果它是强制性的”。原因是VS不想偏离标准那么多。如果您的 .cpp 文件使用头文件中的某些内容,则它必须包含它。这样,即使您关闭预编译头,您的文件也将编译完全相同(只是需要更长的时间)。
  2. 正如其他人所说,如果需要,您可以显式禁用单个文件的预编译头。这个想法是,您应该只在预编译头中包含您在大多数(如果不是全部)文件中使用的那些元素。
  3. 不,无论标头是否预编译,生成的目标代码都应该相同。
© www.soinside.com 2019 - 2024. All rights reserved.