Channels ▼


Precompiled Headers & Normal C++ Semantics

Source Code Accompanies This Article. Download It Now.

Oct01: Precompiled Headers & Normal C++ Semantics

Jeffrey is a C++ consultant who can be contacted at [email protected].

To reduce the amount of time required to build a project, Microsoft's Visual C++ supports precompiled headers. When a header file is included by many C++ files in a project, the header file may be added to the precompiled header and compiled only once for the entire project, rather than once for every C++ file in that project. I have seen the use of precompiled headers halve the build time. Of course, each project will have unique characteristics, and the level of improvement may vary.

However, it is possible to arrange pre-compiled header files in a manner that is inconsistent with normal C++ semantics. Sun compilers, for instance, do not support precompiled headers. Nevertheless, when code is structured properly, precompiled headers can be used with Visual C++ and still be compatible with Sun's compilers.

On Solaris, for instance, Example 1 prints "James Brown." While you might guess that when using the precompiled headers in Visual C++, the program would print "Charlie Daniels," in fact, it instead prints "Charlie Brown." This command line creates a precompiled header when using Visual C++:

cl /c /Ycpch.h pch.cpp

The /Yc option instructs Visual C++ to create a precompiled header, checkpointing the compilation state after pch.h is processed. In Example 1, the precompiled data is kept in a file called "pch.pch" and includes the definition of STR1 and all of iostream.h. Compilation continues after pch.h is processed, but later data is not written to pch.pch. In this example, the definition of STR2 is not included in pch.pch.

The precompiled header data may be used with the following command:

cl /Yupch.h main.cpp

The /Yu option instructs Visual C++ that the source file will attempt to include pch.h. When the include statement is processed, the compiler uses the precompiled data in pch.pch rather than processing pch.h. In Example 1, STR1 is defined as "Charlie" in the precompiled header. STR2 is defined as "Brown" from main.cpp. "Charlie Brown" is printed.

Within the Microsoft development environment, Visual C++ precompiled header specifications for a project can be viewed by pressing Project, Settings, the C/C++ tab, and finally, the category Precompiled Headers.

Typically, one C++ file in the project is set to "Create precompiled header file (.pch) through header <some_filename.h>." This is the first file built for the project. When the debug configuration is built, the data from the compilation of this file, up to and including "<some_filename.h>," is placed in a file named "WinDebug/your_project_name.pch."

Most files will be set to "Use precompiled header file (.pch) through header: <some_filename.h>." This tells Visual C++ that when it parses #include <some_filename.h>, it should disregard "some_filename.h" and insert the precompiled header.

To ensure compatibility, do not put anything in pch.cpp, except #include <pch.h>. As in Example 2, move the definitions of STR1 and STR2 into pch.h using this approach. The performance benefits from the use of precompiled headers is not diminished, the code is easier to read, and the results are consistent with normal C++ semantics.

I was not able to find any documentation from Microsoft that specifically recommends the structure for precompiled header files. However, the comments that Visual C++ inserts into AppWizard projects are consistent with my approach. When Microsoft Visual C++ 6.0 creates a new Win32 Application project (A typical "Hello World" application), it creates a file called "stdafx.h" with the following text:

// stdafx.h : include file for standard system // include files,

// TODO: reference additional headers your // program requires here

It creates a file, "stdafx.cpp," with the text:

// stdafx.cpp : source file that includes just // the standard includes

#include "stdafx.h"

// TODO: reference any additional headers // you need in STDAFX.H

// and not in this file

Clearly, my approach is consistent with Microsoft's architecture, yet still enables compatibility with Solaris.


Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.