预编译头(.pch)


所谓头文件预编译,就是把一个工程(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]

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 文件的计算机上使用该文件。

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

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

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

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

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

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

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

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

如果下列代码:

#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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
预编译文件今天在改一个很大的程序,慢慢看,慢慢改。突然发现一个.c文件,里面什么也没有,就几个文件,我一看,我靠,这不是把简单的问题搞复杂了吗,随手删掉那个c文件。结果不能编译了,我靠:fatal error C1083: Cannot open precompiled header file: \'Debug/v13_3.pch\':No such file or directory怎么rebuild all都不行。上网查了一下,才搞懂了:----------------总结------如果工程很大,文件很多,而有几个文件又是经常要用的,那么1。把这些文件全部写到一个文件里面去,比如写到preh.h2。写一个preh.c,里面只一句话:#include "preh.h"3。对于preh.c,在project setting里面设置creat precompiled headers,对于其他.c文件,设置use precompiled header file//哈哈我试了一下,效果很明显,不用precompiled header,编译一次我可以去上个厕所,用precompiled header,编译的时候,我可以站起来伸个懒腰,活动活动就差不多啦---------转载的文章----------预编译的概念:所谓的预编译就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译文件这些预先编译好的代码可以是任何的C/C++代码--------甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会被经常改变。如果这些代码被修改,则需要重新编译生成预编译文件。注意生成预编译文件是很耗时间的。同时你得注意预编译文件通常很大,通常有6-7M大。注意及时清理那些没有用的预编译文件。也许你会问:现在的编译器都有Time stamp的功能,编译器在编译整个工程的时候,它只会编译那些经过修改的文件,而不会去编译那些从上次编译过,到现在没有被修改过的文件。那么为什么还要预编译文件呢?答案在这里,我们知道编译器是以文件为单位编译的,一个文件经过修改后,会重新编译整个文件,当然在这个文件里包含的所有文件中的东西(.eg Macro, Preprocesser )都要重新处理一遍。VC的预编译文件保存的正是这部分信息。以避免每次都要重新处理这些文件。预编译的作用:根据上文介绍,预编译文件的作用当然就是提高便宜速度了,有了它你没有必要每次都编译那些不需要经常改变的代码。编译性能当然就提高了。预编译的使用:要使用预编译,我们必须指定一个文件,这个文件包含我们不会经常改变的代码和其他的文件,然后我们用这个文件来生成一个预编译文件(.pch文件)想必大家都知道 StdAfx.h这个文件。很多人都认为这是VC提供的一个“系统级别”的,编译器带的一个文件。其实不是的,这个文件可以是任何名字的。我们来考察一个典型的由AppWizard生成的MFC Dialog Based 程序的预编译文件。(因为AppWizard会为我们指定好如何使用预编译文件,默认的是StdAfx.h,这是VC起的名字)。我们会发现这个文件里包含了以下的文件:#include // MFC core and standard components#include // MFC extensions#include // MFC Automation classes#include // MFC support for Internet Explorer 4Common Controls#include <br

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值