/home/bkoz/Desktop/compile_faster_faster_kill_kill_kill/image/pch_duality_light.png

Who can read that handwriting? Sheesh.

Background

PCH is a technique of pre-compiling source headers into an optimized or cached form (binary or text) that facilitates quick reuse by a compiler. Pre. Compiled. Headers.

This technique has existed for some time, first implemented before 1993 in NeXT and Borland compilers, and implemented in GCC for the 3.4 release by Geoff Keating between 2001 and 2002.

Some legal issues needed to be sorted out by the FSF and the GCC Steering Committee before a PCH implementation was checked into GCC. PCH can be considered another link in the list of FSF discussions about exposing GCC's internal state. First was the -save-temps flag, and came the proliferation of -fdump* flags. Next came PCH, and most recently the use of GCC's internal state by a plug-in. In a nutshell, the FSF is wary of possible subversion of the GPL via non-GNU tools. This general issue is examined in detail for the plug-in discussion. Due to the fragility of generated PCH, and the constantly changing nature of GCC internals, FSF fears have not been realized.

Speed is the sole rationale for using PCH. This technique can reliably speed compiles. It is well-used within large C++ projects: libstdc++, boost, Qt. Say, 20-50% increase. See compile tests results.

Given this compile-time speed advantage with PCH, what’s the bother? Just take the performance increase and be glad, one might think.

Issues

But no. After years of use, some common complaints come to the fore:

1) In a project of many source files, who compiles a header? PCH users, that’s who. PCH generation is a bit awkward, with language specification (-x c++) required unless header extensions are un-ambiguous (.hpp, not h). PCH generation is not portable.

2) PCH files must be explicitly generated, and then are implicitly used. Ideally, compiler would self-cache, and figure out what files need to be cached.

3) PCH use is not portable.

4) Creation flags must match use flags. So if the PCH file is generated with compiler flags -O2, the sources must be compiled with flags -02, not -O0.

5) What flags change things? Usually, flags that predefine macros: -I, -fpic, -fexceptions, -frtti, -pthreads, -std=, -O. For starters. The rest have to be discovered experimentally, as there is no definitive list.

6) PCH files can be quite large.

7) PCH files are machine dependant. Even with the same compiler, there is no way to package PCH for general use.

8) Chained PCH files, searching for variant PCH files in an enclosing directory, all slow down the compiler and make the technique less successful. There’s a hard limit of two or three.

9) Forces a prefix file, ie forces a build process where -include all.h precedes all source files. This can change include ordering, resulting in things that compile when a PCH is used, and don’t compile when -include all.h is removed. Or vice versa. This arrangement mandates inefficiency: each source file effectively includes header files that are not necessary, resulting in more work for the compiler and bloated and less efficient translation units.

None: PCHHaters (last edited 2010-12-16 03:02:54 by BenjaminKosnik)