In computer programming, a pre-compiled header is a technique used by some C or C++ compilers to reduce compilation time.

In the C and C++ programming languages, a header file is a file whose text may be automatically included in another source file by the compiler, usually specified by the use of compiler directives in the source file.

Header files can sometimes contain a very large amount of source code (for instance, the header files windows.h and Cocoa/Cocoa.h on Microsoft Windows and Mac OS X, respectively).

To reduce compilation times some compilers allow header files to be precompiled into a form that is faster for the compiler to process. This intermediate form is known as a precompiled header, and is commonly held in a file named with the extensions .pch or .gch.

A related feature is the prefix header, which is a file that is automatically included by the compiler without requiring the use of any compiler directives. Prefix headers are commonly precompiled, but not all precompiled headers are prefix headers.

Simple Example

Given a C++ file source.cpp that includes header.hpp:

// header.hpp   
  
  

 

// source.cpp  
 
#include 
"header.hpp"   
  
  

When compiling source.cpp for the first time with the pre-compiled header feature turned on, the compiler will generate a pre-compiled header, header.pch. The next time, the compiler can skip the compilation phase relating to header.hpp and instead use header.pch directly.

Example with forward declaration

We have two classes A (in A.h and A.cpp) and B (in B.h and B.cpp). Class A is quite simple:

 

class A {   
  
     
  
}; 

When class B is composed by an attribute of class A, normally the class A will become part of the class:

 


To prevent recompilation of B1.h, when class A changes, sometimes pointer syntax will be used; B2.h:

 

#include "A.h"   
  
class B1 {   
  
     
  
  A mA;   
  
}; 

 

class A;   
  
class B2 {   
  
     
  
  A
* mA;   
  
};

 

As can be seen, a forward declaration of class A is used instead of including the header. But this pointer syntax complicates the usage of the variable as price for lesser compilation.

 This problem can be solved by the usage of pre-compiled headers. We can use the easier syntax in B1.h and advise the compiler to use pre-compiled headers. Then the files A.pch and B1.pch will be created.

 When the class A is changed now, only A.h has to be parsed again and written to the pre-compiled header A.pch. As the file B1.h is not changed, it does not need to be parsed again and the already existing pre-compiled header B1.pch can be used.

Common Implementations

 stdafx.h

stdafx.h is a file, generated by Microsoft Visual Studio IDE wizards, that describes both standard system and project specific include files that are used frequently but hardly ever changed.

 Compatible compilers (for example, Visual C++ 6.0 and newer) will pre-compile this file to reduce overall compile times. Visual C++ will not compile anything before the #include "stdafx.h" in the source file, unless the compile option /Yu'stdafx.h' is unchecked (by default); it assumes all code in the source up to and including that line is already compiled.

 The AFX in stdafx.h stands for Application Framework eXtensions. AFX was the original abbreviation for the Microsoft Foundation Classes (MFC). Optionally, Visual Studio projects may avoid pre-compiled headers, as well as they may specify an alternative name (though stdafx.h is used by default).

 GCC

Pre-compiled headers are supported in GCC (3.4 and newer). GCC's approach is similar to these of VC and compatible compilers. GCC saves the pre-compiled version using a ".gch" suffix. When compiling source files, the compiler checks whether those files are present. If possible, the pre-compiled version is used. If this is not possible, then, the normal header is still present as a fall-back plan.

 GCC can only use the pre-compiled version if the same compiler switches are set as when the header was compiled and it may use at most one. Further, only preprocessor instructions may be placed before the pre-compiled header (because it must be directly or indirectly included through another normal header, before any compilable code).

 GCC automatically identifies most header files using their extension. However, if this fails (e.g. because of non standard header extensions), the -x switch can be used to be sure that GCC treats the file as a header instead of a normal source file.

 C++Builder

In the default project configuration, the C++Builder compiler implicitly generates precompiled headers for all headers included by a source module until the line #pragma hdrstop is found. Precompiled headers are shared for all modules of the project if possible. For example, when working with the Visual Component Library, it is common to include the <vcl.h> header first which contains most of the commonly used VCL header files. Thus, the precompiled header can be shared across all project modules, which dramatically reduces the build times.

 In addition, C++Builder can be instrumented to use a specific header file as precompiled header, similar to the mechanism provided by Visual C++.

 C++Builder 2009 introduces a "Precompiled Header Wizard" which parses all source modules of the project for included header files, classifies them (i.e. excludes header files if they are part of the project or do not have an Include guard) and generates and tests a precompiled header for the specified files automatically.

 

预编译头文件(一般扩展名为.PCH),是把一个工程中较稳定的代码预先编译好放在一个文件(.PCH)里.这些预先编译好的代码可以是任何的C/C++代码--甚至可以是inline函数,只它们在整个工程中是较为稳定的,即在工程开发过程中不会经常被修改的代码.

为什么需要预编译头文件?一言以蔽之:提高编译速度.一般地,编译器以文件为单位编译,如果修改了一工程中的一个文件则所有文件都要重新编译,包括头文件里的所有东西(eg.Macro宏,Preprocessor预处理),而VC程序中,这些头文件中所包括的东西往往是非常大的,编译之将占很长的时间.但它们又不常被修改,是较稳定的,为单独的一个小文件而重新编译整个工程的所有文件导致编译效率下降,因此引入了.PCH文件.

如何使用预编译头文件以提高编译速度?要使用预编译头文件,必须指定一个头文件(.H),它包含我们不会经常修改的代码和其他的头文件,然后用这个头文件(.H)来生成一个预编译头文件(.PCH)VC默认的头文件就是StdAfx.h,因为头文件是不能编译的,所以我们还需要一个.CPP文件来作桥梁,VC默认的文件为StdAfx.cpp,这个文件里只有一句代码就是:#include "StdAfx.h".接下来要用它生成.PCH文件,涉及到几个重要的预编译指令:/Yu,/Yc,/Yx,/Fp.简单地说,/Yc是用来生成.PCH文件的编译开关.在Project->setting->C/C++的Category里的Precompiled Header,然后在左边的树形视图中选择用来编译生成.PCH文件的.CPP文件(默认即StdAfx.cpp)你就可以看到/Yc这个开关,它表示这个文件编译了以后是否生成.PCH文件(可能/Yc的c表示create)./Fp指令指定生成的.PCH文件的名字及路径(可能/Fp的p代表path)./Yu的u即use使用,工程中只要包括了.H文件的文件都会有这个/Yu指令.如果选择自动Automatic...的话则原来为/Yc的地方就换成了/Yx指令.如果选择自动,则每次编译时编译器会看以前有没有生成过.PCH文件,有则不现生成否则就再次编译产生.PCH文件.

注意:

A,实际上,由Appzard项目向导生成的默认的头文件及CPP文件StdAfx.h和StdAfx.cpp可以是任何名字的.原因很简单.但如果你要这样做就要记得修改相应的Project->setting...下的几个预编译指令(/Yc,/Yu,/Yx,/Fp)的参数.

B.在任何一个包括了将要预编译的头文件而使用了.PCH文件的工程文件的开头,一定必须要是在最开头,你要包含那个指定生成.PCH文件的.H文件 (通过.CPP文件包括,默认为StdAfx.cpp) ,如果没包括将产生我最开头产生的错误.如果不是在最开头包括将产生让你意想不到的莫名其妙错误,如若不信,盍为试之?

C.预编译文件.PCH生成之很耗时间,而且生成之后它也很占磁盘空间,常在5-6M,注意项目完成之后及时清理无用的.PCH文件以节约磁盘空间.

D.如果丢了或删了.PCH文件而以后要再修改工程文件时,可将指定的/Yc的.CPP文件(默认为StdAfx.cpp)重新编译一次即可再次生成.PCH文件,不用傻傻的按F7或Rebuild All