`

VC 预编译头

阅读更多

预编译头的概念:
在很多程序中,每个源文件都存在一些相同的部分。比如要包括相同的一些头文件,而且这些头文件可能很长,例如window.h。如果用普通的方法编译这些源文件,对这些头文件在每个源文件中的出现都要重新编译,作了很多重复工作。如果能将这些头文件专门进行编译,并且把结果存储起来。然后在编译包含这些头文件的源文件时,使用上述结果替代头文件在源文件中的出现,就可以大大减少工作量。Microsoft Visual C++提供的“预编译头文件”机制就支持这一功能。


所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.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 <afxwin.h>      // MFC core and standard components

#include <afxext.h>      // MFC extensions

#include <afxdisp.h>    // MFC Automation classes

#include <afxdtctl.h>        // MFC support for Internet Explorer 4 Common Controls

#include <afxcmn.h>  

这些正是使用MFC的必须包含的头文件,当然我们不太可能在我们的工程中修改这些头文件的,所以说他们是稳定的。

那么我们如何指定它来生成预编译头文件。我们知道一个头文件是不能编译的。所以我们还需要一个cpp文件来生成.pch 文件。这个文件默认的就是StdAfx.cpp。在这个文件里只有一句代码就是:#include “Stdafx.h”。原因是理所当然的,我们仅仅是要它能够编译而已―――也就是说,要的只是它的.cpp的扩展名。我们可以用/Yc编译开关来指定StdAfx.cpp来生成一个.pch文件,通过/Fp编译开关来指定生成的pch文件的名字。打开project ->Setting->C/C++ 对话框。把Category指向Precompiled Header。

在Project Options(右下角的那个白的地方)可以看到 /Fp “debug/PCH.pch”,这就是指定生成的.pch文件的名字,默认的通常是 <工程名>.pch(我的示例工程名就是PCH)。

这时原来的Project Option变成了 Source File Option(原来是工程,现在是一个文件,当然变了)。在这里我们可以看到 /Yc开关,/Yc的作用就是指定这个文件来创建一个Pch文件。/Yc后面的文件名是那个包含了稳定代码的头文件,一个工程里只能有一个文件的可以有YC开关。VC就根据这个选项把 StdAfx.cpp编译成一个Obj文件和一个PCH文件。

在这里,Precomplier 选择了 Use ………一项,头文件是我们指定创建PCH 文件的stdafx.h文件。事实上,这里是使用工程里的设置,/Yu”stdafx.h”。

这样,我们就设置好了预编译头文件。也就是说,我们可以使用预编译头功能了。以下是注意事项:

1):如果使用了/Yu,就是说使用了预编译,我们在每个.cpp文件的最开头,我强调一遍是最开头,包含 你指定产生pch文件的.h文件(默认是stdafx.h)不然就会有问题。如果你没有包含这个文件,就告诉你Unexpected file end. 如果你不是在最开头包含的,你自己试以下就知道了,绝对有很惊人的效果…..

2)如果你把pch文件不小心丢了,根据以上的分析,你只要让编译器生成一个pch文件就可以了。也就是说把 stdafx.cpp(即指定/Yc的那个cpp文件)从新编译一遍就可以了。当然你可以傻傻的 Rebuild all。简单一点就是选择那个cpp文件,按一下Ctrl + F7就可以了。

方法二:自动使用

很简单只要指定/YX就可以了。或者在上图中选择Automatic………就可以了。注意的事情是如果你指定了/Yc /Yu的话,/Yx是会被忽略的。前者的优先级别高一些.
下面从另一个角度再看一下:
假设每个源文件的相同部分都出现在文件的开始部分。这一假设是很现实的。那么相同部分的结尾如何定位呢?由两种方法,一是由程序员在源文件中用#pragma hdrstop标记;二是指定对某个头文件的包含指示符(#include directive)作为结束标志。这个头文件被称为through header file,在/Yc或者/Yu命令参数中指明。
在编译第一个源文件时,将从文件头到预编译部分结束处的编译结果存储到一个预编译头文件中,扩展名通常是pch。这个过程称为预编译头文件的生成。这一步工作需要指定/Yc参数。在对其他源文件进行编译时,使用这个预编译头文件,此时用/Yu参数。生成的预编译头文件的名字通过/Fp参数指定。
下面举一个例子。假设Project中共用的宏定义,常量定义,头文件引用都放在prechdr.h中。我编辑一个prechdr.cpp来#include “prechdr.h”。对prechdr.cpp编译时就可以生成包含prechdr.h中内容的预编译头文件:
cl /Ycprechdr.h /Fp.\Debug\prechdr.pch prechdr.cpp
这样,就创建了prechdr.pch。在编译其他源文件时,使用prechdr.pch:
cl /Yuprechdr.h /Fp.\Debug\prechdr.pch others.cpp
在IDE中,可以将Project Settings设置成/Yuprechdr.h /Fp.\Debug\prechdr.pch。然后将prechdr.cpp的C++ tab中Precompile类别设置成Use precompiled header,即在使用Project Settings的基础上增加了/Yc参数。当/Yc和/Yu共存时,只有/Yc起作用。IDE在build Project时会最先编译prechdr.cpp以创建预编译头文件供其他源文件使用。









分享到:
评论

相关推荐

    什么是预编译

    2. 使用 VC 的预编译头文件:VC 提供了一个名为 StdAfx.h 的预编译头文件,包含了 MFC 的核心组件和标准组件。 预编译头文件的优点是可以提高编译速度,因为编译器不需要每次都重新编译相同的代码。但是,生成预...

    Vc自动编译脚本文件生成

    标题中的“Vc自动编译脚本文件生成”指的是在软件开发过程中,为了提高效率,开发者通常会创建自动化脚本来编译Visual C++(Vc)项目。这涉及到批处理脚本技术,如Windows下的批处理文件(.bat),用于自动化执行一...

    MFC高速二维曲线控件示例程序,VC2017编译通过

    老版本的VC使用stdafx.h作为预编译头,VC2017使用pch.h作为预编译头,为了方便,干脆取消掉预编译头:属性-&gt;c/c++-&gt;预编译头-&gt;不使用预编译头。在程序中我用到了控件的曲线自适应功能,会根据数据自动的将曲线填满...

    C语言预编译命令用法

    标题:C语言预编译命令用法 描述与知识点详解: C语言的预编译命令在编程中扮演着至关重要的角色,它们允许开发者在编译阶段执行一系列操作,包括但不限于宏定义、条件编译和文件包含等。在给定的描述中提到的“#...

    VC 6.0下编译调试ffmpeg

    在VC 6.0下,你可能需要手动调整预处理器宏来实现类似的功能。例如,为了启用某个特定的编解码器,你可能需要在项目属性的`C/C++` -&gt; `Preprocessor` -&gt; `Preprocessor Definitions`中添加相应的宏定义。 ### 9. ...

    lua VC6可编译源码

    4. **预编译的库文件**:在“debug”目录下,应该有预编译的lua.lib文件,这是用于调试的动态链接库或静态链接库。 5. **可能的配置文件**:如makefile或批处理文件,帮助用户在不同的操作系统或编译环境中编译源码...

    VC6.0编译环境介绍

    ### VC6.0编译环境介绍 #### 一、概述 VC6.0,全称为Microsoft Visual C++ 6.0,是微软公司发布的一款功能强大的集成开发环境(IDE),适用于Windows平台上的C/C++程序开发。尽管后来出现了更为先进的版本如Visual...

    x264-VC6.0编译通过加代码完整注释版.rar

    4. **配置编译选项**:在项目设置中,配置编译器选项,包括优化级别、警告级别以及预处理器定义等,以适应x264的编译需求。 5. **编译和链接**:保存设置后,尝试编译项目。如果一切顺利,你应该能在输出窗口看到...

    VC6中MFC常见编译错误

    通常,当设置了参数/Yu"stdafx.h"时,意味着每个源文件(.cpp)都需要包含"stdafx.h"来启动预编译头。若缺少这个包含语句,编译器就会报此错误。解决这个问题的方法是在每个源文件的开头添加`#include "stdafx.h"`。预...

    vc的stdafx文件和C1083、C1010错误

    通过预编译头文件,可以将这些常用头文件预先编译成一个二进制文件(.pch 文件),这样在后续的编译过程中,只需要包含预编译后的文件即可,大大加快了编译速度。 #### 知识点二:`stdafx.h` 和 `StdAfx.cpp` 的...

    openssl 1.0.2o经vc6.0编译过的源码和.dll

    - 运行 `Configure` 脚本进行预编译配置,选择合适的平台和编译选项,如:`perl Configure VC-WIN32 no-asm`。 - 使用 `ms\do_ms.bat` 脚本来生成项目文件。 - 在 VC6.0 中打开生成的项目文件,编译并链接生成 ....

    VC 编译环境(设置)介绍

    **VC编译环境设置介绍** 在Windows操作系统上开发C++程序时,Microsoft Visual C++(简称VC)是一款常用的集成开发环境。本篇文章将详细介绍如何设置和配置VC6.0及VC2005的编译环境,以确保顺利进行C++编程。 ## ...

    tinyxml vc6.0编译通过,使用手册

    - **预处理器定义**:可能需要在编译选项中添加预处理器宏,以便TinyXML识别当前的编译环境。 - **使用手册**:提供的使用手册将详细解释如何在项目中引入TinyXML,如何创建XML文档,如何读取和修改XML数据,以及...

    winXP VC2010编译的最新 curl 7.25.0(exe, dll, lib)

    libcurl配置 vc windows vs2008/2010 ... 解压 打开根目录下的curlxxx....2、加入预编译选项:项目-&gt;属性-&gt;c/c++ -&gt;预处理器-&gt;预处理器,把 ;BUILDING_LIBCURL;HTTP_ONLY复制进去(注意不要丢了";") 就可以静态编译了

    VC6的完整编译工程与结果

    5. **预编译头文件**:.pch文件,用于提高编译速度,预先编译常用头文件。 6. **配置文件**:如设置编译器选项、链接器选项、库依赖等的设置文件。 7. **构建脚本**:如批处理文件或Makefile,自动化编译和构建过程...

    浅谈VC中预编译的头文件放那里的问题分析

    而`stdafx.cpp`仅负责包含`stdafx.h`,这样编译器会处理`stdafx.cpp`中的`#include "stdafx.h"`,生成预编译头对象`stdafx.obj`。 预编译头文件的正确使用有以下几点需要注意: 1. 只有在`stdafx.cpp`中包含`stdafx...

    VS90SP1-KB976656-x86-VC2008.zip

    《VC2008预编译头错误C1859的解决之道》 在编程领域,尤其是使用Microsoft Visual Studio 2008 (VS2008)进行开发时,开发者可能会遇到一个棘手的问题——"fatal error C1859:意外的预编译头错误"。这个问题通常是...

    VC编译参数设置详解

    ### VC编译参数设置详解 #### 一、概述 本文档详细介绍了Visual C++ (VC) 编译器中的各种编译参数及其设置方法。这些参数对于开发人员来说非常重要,因为它们直接影响到编译过程、代码质量以及最终生成的可执行...

    VC命令行编译C++

    - `option`:指定一系列编译参数,如优化等级、预处理器指令、警告级别等。 - `file`:表示待编译的源文件,可以是一个或多个。 - `lib`:指明程序所需的依赖库,确保链接时能够找到所需的函数和数据。 - `command-...

Global site tag (gtag.js) - Google Analytics