52

Why use precompiled headers?


Reading the responses, I suspect what I've been doing with them is kind of stupid:

#pragma once

// Defines used for production versions

#ifndef PRODUCTION
#define eMsg(x) (x) // Show error messages
#define eAsciiMsg(x) (x)
#else
#define eMsg(x) (L"") // Don't show error messages
#define eAsciiMsg(x) ("")
#endif // PRODUCTION

#include "targetver.h"
#include "version.h"

// Enable "unsafe", but much faster string functions
#define _CRT_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_WARNINGS

// Standard includes
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <direct.h>
#include <cstring>
#ifdef _DEBUG
#include <cstdlib>
#endif

// Standard Template Library
#include <bitset>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
#include <string>
#include <numeric>

// Boost libraries
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/scoped_array.hpp>

//Windows includes
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "FILETIME_Comparisons.h"
#include <shlwapi.h>
#include <Shellapi.h>
#include <psapi.h>
#include <imagehlp.h>
#include <mscat.h>
#include <Softpub.h>
#include <sfc.h>
#pragma comment(lib, "wintrust.lib")
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"Psapi.lib")
#pragma comment(lib,"shlwapi.lib")
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"Advapi32.lib")
#pragma comment(lib,"Shell32.lib")
#pragma comment(lib,"Sfc.lib")
#pragma comment(lib,"Version.lib")

// Crypto ++ libraries
#ifdef _DEBUG
#pragma comment(lib,"cryptlibd.lib")
#else
#pragma comment(lib,"cryptlib.lib")
#endif
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <md5.h>
#include <sha.h>

// String libraries
#include "stringUnicodeConversions.h"
#include "expandEnvStrings.h"
#include "randomString.h"
#include "getShortPathName.h"

// Regular Expression Libraries
#include "fpattern.h"

// File Result Record
#include "unixTimeToFileTime.h"
#include "fileData.h"

// Writer
#include "writeFileData.h"

// Criteria Structure System
#include "priorities.h"
#include "criterion.H"
#include "OPSTRUCT.H"
#include "regexClass.H"
#include "FILTER.h"

// Sub Programs Root Class
#include "subProgramClass.h"

// Global data
#include "globalOptions.h"

// Logger
#include "logger.h"

// Console parser
#include "consoleParser.h"

// Timeout handler
#include "timeoutThread.h"

// Zip library
#include "zip.h"
#include "unzip.h"
#include "zipIt.h"

// Scanner
#include "mainScanner.h"
#include "filesScanner.h"

// Sub Programs
#include "volumeEnumerate.h"
#include "clsidCompressor.h"
#include "times.h"
#include "exec.h"
#include "uZip.h"

// 64 bit support
#include "disable64.h"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • 3
    One important note on Visual Studio: make sure the first #include in each header is #include "stdafx.h" or your files will not be parsed! Stupid, I know. But it's an easy mistake to make. – rlbond May 24 '09 at 06:44
  • 2
    To be more specific, anything ABOVE #include "stdafx.h" is not parsed. See http://en.wikipedia.org/wiki/Precompiled_header – rlbond May 24 '09 at 06:46

5 Answers5

72

In C/C++, the #include mechanism is a textual copy of the file specified into the current file. Headers include other headers (which include yet other headers), so when you do a #include, it could be adding tens of thousands of lines of C++ into each cpp file (or cxx, c, whatever), all of which need to be compiled each time. This can be a severe bottleneck for large projects.

Precompiled headers speed this up by compiling each header once, then including that compiled state into the cpp they are included in.

Gulzar
  • 23,452
  • 27
  • 113
  • 201
Todd Gardner
  • 13,313
  • 39
  • 51
  • 1
    I was looking into an insight what actually a precompiled header is cause as we know header files are not translation unit by themselves. Nice explanation, thx. – macroland Nov 23 '15 at 21:59
  • 1
    What is the meanig of "compiling each header once"? Are the headers compiled? There are just declarations ... no? – TonySalimi Jan 30 '19 at 14:58
  • @Gupta Well, declarations (such as `int foo(int a, int b)`) need to be "compiled" - i.e. processed by the compiler, as well. Aside from that, as opposed to headers in C, headers in C++ tend to include actual code as well (which is arguably not the best idea). Especially when considering templates, which generally speaking must reside in header files. – Aviv Cohn Nov 22 '20 at 15:56
  • If my project has only one `.cpp` file that includes the precompiled header. Would using a precompiled header in this case speed up the compilation? – mercury0114 Dec 04 '20 at 13:30
  • @mercury0114 if you change your ```.cpp``` file a lot but not your corresponding ```.h``` file, then you might still benefit from a precompiled header file. Just put all your ```#include``` lines in ```foo.h``` and have your single ```foo.cpp``` only ```#include "foo.h"```. – Bodo Thiesen Mar 20 '21 at 00:49
43

It compiles a lot quicker. C++ compilation takes years without them. Try comparing some time in a large project!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rlbond
  • 65,341
  • 56
  • 178
  • 228
  • 2
    If a project is small - less than 10 files, should precompiled headers still be used? – Danijel Feb 08 '21 at 15:20
  • 1
    How big are the files? – KcFnMi Feb 15 '21 at 10:13
  • 1
    @Danijel you should check it for yourself. If you switch to precompiled headers and recompile a few times and notice no discernable difference then it is pointless. If you can tell that it compiles faster without looking at the clock, then yes, you should be using them. –  Mar 12 '22 at 08:21
12

Re: your current usage, if you have a target with a very large number of files, it may still be faster to use PCH in that way - try switching them off to find out. It depends: if you have a lot of headers of your own, and you change them only infrequently, and you have a very large number of source files that you change much more frequently, then your PCH usage will cut rebuild times.

But normal advice is to only put things in PCH that never change, because there is a certain overhead to producing the PCH itself. If you trigger that off with every rebuild (by constantly tweaking one of your headers), using PCH may make the rebuild slower.

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
7

So you don't have to compile them every time you build your project. They're used for system headers that aren't going to change.

n8gray
  • 4,939
  • 3
  • 36
  • 33
7

It speeds up compilation.

When you're including headers from other projects, you don't expect to change them. If you put these into a precompiled header, then that code will not have to be recompiled when you make changes to your source code. This reduces repetitive compilation of unchanged code, speeding up compile time.

swongu
  • 2,229
  • 3
  • 19
  • 24