预编译头(.pch)

来源:互联网 发布:第三方网络销售平台 编辑:程序博客网 时间:2024/06/07 10:21


所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。

一、预编译头文件说明所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。编 译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指 令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。因此,所有的CPP实现文件第一条语句都是:#include "stdafx.h"。另外,每一个实现文件CPP都包含了如下语句:#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif这是表示,如果生成调试版本,要指示当前文件的名称。__FILE__是一个宏,在编译器编译过程中给它赋值为当前正在编译的文件名称。VC.NET 默认情况下使用预编译头(/Yu),不明白的在加入新.h文件后编译时总出现fatal error C1010: 在查找预编译头指令时遇到意外的文件结尾的错误。解决方法是在include头文件的地方加上#include "stdafx.h",或者打项目属性,找到“C/C++”文件夹,单击“预编译头”属性页。修改“创建/使用预编译头”属性为“不使用预编译头”。


预编译头就是将程序的头文件部分编译成一个二进制中间文件,提高整个工程的编译效率,一般以.pch格式存储。      1. 在编译器重已经采用了时间戳的方式,为何还需要预编头呢?        对.obj加以时间戳的方式,可以根据时间戳来决定哪些文件需要重新编译,从而提高效率。但重新编译这个文件,包括这个文件的头文件里的信息和预处理(指头文件中的预处理)都重新进行一遍,而预编译头正是解决了这个问题,将稳定的头文件内容预先编译为一个二进制中间文件。      2. 只有头文件如何编译呢?        编译器无法直接编译头文件,那么就需要一个CPP和结合头文件一起编译,这样就是为什么通常MFC工程中存在一个StdAfx.cpp,其内容仅仅显示:    // stdafx.cpp : 只包括标准包含文件的源文件    // TurnRound.pch 将作为预编译头    // stdafx.obj 将包含预编译类型信息    #include "stdafx.h"        通常将常用的头文件都放到stdafx.h头文件中。
</pre><pre class="html" name="code" snippet_file_name="blog_20160928_4_2143430" code_snippet_id="1905775">问题的关键是:预编译的内涵是什么?1.你可以自己先创建一个h文件,然后把你要引用到的h文件#include进来,譬如创建mystdafx.h如下    #include <stdio.h>     #include <string>     #include "boost/filesystem.hpp" 2.然后创建一cpp文件如mystdafx.cpp如下    #include "mystdafx.h" 3.工程里添加引用这两文件4.鼠标右键点击mystdafx.cpp,设置它的属性    4.1 创建/使用预编译头:/Yc     4.2 通过文件使用/创建PCH: mystdafx.h     4.3 预编译头文件:$(IntDir)\$(TargetName).pch注:我用VS2008。大体的思路都差不多。


指示编译器在当前编译中使用现有预编译头(.pch)文件。

语法

复制
/Yu[filename]

Arguments

filename

头文件的名称,它包含在使用 #include 预处理器指令的源文件中。

备注

对于创建预编译头的 /Yc 选项和任何随后指示使用预编译头的/Yu 选项,包含文件的名称必须相同。

对于 /Ycfilename 指定预编译停止的位置;编译器预编译直到filename 的所有代码,并使用包含文件的基名称和 .pch 扩展名对得到的预编译头进行命名。

该 .pch 文件必须是使用 /Yc 创建的。

编译器将所有在 .h 文件之前出现的代码视为已经过预编译。它刚好跳到与 .h 文件关联的#include 指令之外,使用 .pch 文件中包含的代码,然后编译filename 之后的所有代码。

在命令行上,/Yufilename 之间不允许存在空格。

如果指定 /Yu 选项但不带文件名,则源程序必须包含指定预编译头(.pch 文件)的文件名的#pragma hdrstop 杂注。在这种情况下,编译器将使用由/Fp(命名 .Pch 文件) 命名的预编译头(.pch 文件)。编译器跳到该杂注所在的位置,从由杂注指定的预编译头文件还原编译状态,然后只编译杂注后面的代码。如果#pragma hdrstop 没有指定文件名,编译器将查找其名称从扩展名为 .pch 的源文件的基名称派生的文件。还可以使用/Fp 选项指定不同的 .pch 文件。

如果指定 /Yu 选项但不带文件名,且未能指定 hdrstop 杂注,则生成错误信息,且编译不成功。

如果 /Ycfilename/Yufilename 选项出现在同一命令行上,并且引用同一文件名,则 /Ycfilename 优先,对直到命名文件(包含该文件)的所有代码进行预编译。此功能简化了生成文件的编写。

由于 .pch 文件包含的信息涉及计算机环境以及程序的内存地址,因此,只应在创建 pch 文件的计算机上使用该文件。

有关预编译头的更多信息,请参见:

  • /Y(预编译头)

  • 创建预编译的头文件

在 Visual Studio 开发环境中设置此编译器选项

  1. 在项目中的 .cpp 文件中指定 /Yc(创建预编译的头文件)。

  2. 打开项目的“属性页”对话框。有关详细信息,请参见如何:打开项目属性页。

  3. 单击“C/C++”文件夹。

  4. 单击“预编译头”属性页。

  5. 修改“通过文件创建/使用 PCH”属性或“创建/使用预编译头”属性。

以编程方式设置此编译器选项

  • 请参见PrecompiledHeaderThroughUsePrecompiledHeader

示例

如果下列代码:

复制
#include <afxwin.h>   // Include header for class library#include "resource.h" // Include resource definitions#include "myapp.h"    // Include information specific to this app...

使用命令行 CL /YuMYAPP.H PROG.CPP 进行编译,则编译器不处理这三个 include 语句,但使用 MYAPP.pch 中的预编译代码,从而节省了用于预处理所有这三个文件(以及它们可能包含的任何文件)的时间。

可以将 /Fp(命名 .Pch 文件) 选项与 /Yu 选项一起使用,以指定 .pch 文件的名称(如果该名称不同于 /Yc 的文件名参数或源文件的基名称),如下所示:

复制
CL /YuMYAPP.H /FpMYPCH.pch PROG.CPP

此命令指定名为 MYPCH.pch 的预编译头文件。编译器使用其内容还原所有头文件(一直到 MYAPP.h 并包含该文件)的预编译状态。然后编译器编译在 MYAPP.h 的include 语句之后出现的代码。


https://msdn.microsoft.com/zh-cn/library/z0atkd6c.aspx


0 0
原创粉丝点击