如何在项目中实现预编译头
我了解预编译头背后的目的和推理。然而,实施时有哪些规则呢?根据我的理解,它是这样的:
- 将您的项目设置为使用带有 YU 指令的预编译头。
- 创建 stdafx.h 文件并将其设置为预编译头。
- 将此作为每个 .h 文件中的顶部包含语句。
这是正确的吗?您是否应该将其排除在预编译头中包含的文件中?目前,当我遵循我的直觉时,出现以下编译错误:
错误 C2857:“#include”语句 使用 /Ycstdafx.h 指定 未找到命令行选项 源文件
命令行选项如下:
/Od /I “../外部/PlatformSDK/包含”/I “..”/I“../外部/atlmfc/包含” /D“_DEBUG”/D“_UNICODE”/D“UNICODE” /Gm /EHsc /RTC1 /MDd /Yc"stdafx.h" /Fp"....\Output\LudoCore\Debug\LudoCore.pch" /Fo"....\Output\LudoCore\Debug\" /Fd"....\Output\LudoCore\Debug\vc80.pdb" /W4 /WX /nologo /c /ZI /TP /wd4201 /错误报告:提示
I understand the purpose and reasoning behind precompiled headers. However, what are the rules when implementing them? From my understanding, it goes something like this:
- Set your project up to use precompiled headers with the YU directive.
- Create your stdafx.h file and set that to be your precompiled header.
- Include this as the top include statement in each of your .h files.
It this correct? Should you exclude the including it in the files that are included within your precompiled header? Currently, I get the following compilation error when following my intuition with this:
error C2857: '#include' statement
specified with the /Ycstdafx.h
command-line option was not found in
the source file
The command-line options are as such:
/Od /I
"../External/PlatformSDK/Include" /I
".." /I "../External/atlmfc/Include"
/D "_DEBUG" /D "_UNICODE" /D "UNICODE"
/Gm /EHsc /RTC1 /MDd /Yc"stdafx.h"
/Fp"....\Output\LudoCore\Debug\LudoCore.pch"
/Fo"....\Output\LudoCore\Debug\"
/Fd"....\Output\LudoCore\Debug\vc80.pdb"
/W4 /WX /nologo /c /ZI /TP /wd4201
/errorReport:prompt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的 stdafx.cpp 应包含 stdafx.h 并使用
/Yc"stdafx.h"
构建。您的其他 *.cpp 应包含 stdafx.h 并使用
/Yu"stdafx.h"
构建。请注意编译器选项中使用的双引号字符!
以下是用于 stdafx.cpp 创建预编译头的 Visual Studio 设置的屏幕截图:
以下是相应的命令-line 选项(只读,但反映其他页面上指定的设置;请注意,IDE 在编译器选项中的文件名周围插入双引号字符):
这是我的 stdafx.cpp 文件中的内容:
You stdafx.cpp should include stdafx.h and be built using
/Yc"stdafx.h"
.Your other *.cpp should be include stdafx.h and be built using
/Yu"stdafx.h"
.Note the double-quote characters used in the compiler options!
Here's a screenshot of the Visual Studio settings for stdafx.cpp to create a precompiled header:
Here are the corresponding command-line options (which are read-only but reflect the settings specified on other pages; note that the IDE inserts double-quote characters around the filename, in the compiler option):
This is what's in my stdafx.cpp file:
Visual Studio 不仅可以按项目存储预编译头属性,还可以按源文件存储预编译头属性。
默认情况下,所有属性都设置为“从父级或项目默认值继承”,这仅显示该属性的父级对象的值,但一旦在子级别(在本例中为 .cpp 文件)覆盖,该文件将忽略父级属性的更改。
您想要的配置是:
Visual studio can store pre-compiled header properties not just by project but by source file.
By default all properties are set to "inherit from parent or project defaults" which just shows the parent object's value for that property, but once overriden at a child level (in this case a .cpp file) the file ignores changes from the parent property.
The configuration you want is:
您的
#include "stdafx.h"
应该是每个 cpp 文件的第一行。它不应该在 .h 文件中使用。除此之外,你是对的。Your
#include "stdafx.h"
should be the first line of each cpp file. It shouldn't be used in the .h files. Other than that you're about right.“stdafx”只是一个约定。这绝不是强制性的。在多项目解决方案中,我对不同部分使用了具有多个预编译标头的其他设置。例如,让您的 UI 项目共享一个 PCH,并为您的数据库项目共享另一个 PCH 可能会很有用。
相关组件是列出预编译标头的 Xh 文件、仅包含 Xh(并且本身不添加任何代码)的 X.cpp 文件,以及通过使用编译器选项
/Yc
。当您现在使用
/Yu"X.pch"
编译 Y.cpp 文件时,编译器会读取并丢弃#include "Xh"< 之前的所有内容/代码>。此时,它会将其内部状态替换为 X.pch 中存储的状态,但输入流除外(仍为 Y.cpp,文件指针设置为
#include "Xh"
后的下一行)。"stdafx" is just a convention. It's in no way mandatory. In a multi-project solution, I've used other setups with multiple pre-compiled headers for different parts. E.g. it may be useful to have one PCH shared by your UI projects, and another one for your database projects.
The relevant components are the X.h file listing precompilable headers, the X.cpp file that includes only X.h (and adds no code itself), and the X.pch file created by compiling X.cpp (and thus X.h) with compiler option
/Yc
.When you're now compiling Y.cpp file with
/Yu"X.pch"
, the compiler reads and discards everything up to#include "X.h"
. At that point it replaces its internal state with the state stored in X.pch, except for the input stream (remains Y.cpp, with the file pointer set to the next line after#include "X.h"
).