Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
HP.com home

Compaq C++ User Documentation

 

Compaq C++

Compaq C++
Using Compaq C++ for Tru64 UNIX and Linux Alpha


Previous Contents Index


Chapter 6
Precompiled Headers

Using precompiled header (PCH) files can dramatically reduce compilation time in environments where:

  • Many primary sources include the same set of headers in the same order.
  • These headers introduce many lines of code.

The Version 6.0 compiler provides a mechanism that, in effect, takes a snapshot of the compilation state at a particular point and writes it to a disk file before completing the compilation. Then, when recompiling the same source file or compiling another file with the same set of headers, the compiler can recognize the snapshop point, verify that the corresponding PCH file is reusable, and read it back in.

PCH files can be large (from a minimum of 250 KB to several megabytes or more). To achieve the maximum performance gain at the smallest cost, as many sources as possible should share the same PCH files. The performance gain is thereby achieved at the smallest cost in disk storage. Compaq C++ for Linux Alpha does not support precompiled headers.

This chapter describes mechanisms used to generate and process PCH files. Topics include the following:

Section 6.5 describes command-line options.

6.1 Automatic Precompiled Header Processing

You enable automatic precompiled header processing by specifying the -pch command-line option (see Section 6.5n ). The compiler automatically looks for a qualifying precompiled header file to read in, or it creates one for use on a subsequent compilation. In some cases, it performs both operations.

The PCH file contains a snapshot of all the code preceding the header stop point, typically the first token in the primary source file that does not belong to a preprocessing directive. You also can specify the stop point directly by using #pragma hdrstop if that comes first (see <REFERENCE>(wys_ctrl_hdrs_sec)). For example:


     #include "xxx.h" 
     #include "yyy.h" 
     int i; 

The header stop point is int (the first nonpreprocessor token), and the PCH file contains a snapshot reflecting the inclusion of xxx.h and yyy.h . If the first non preprocessor token or the #pragma hdrstop appears within a #if block, the header stop point is the outermost enclosing #if . For example:


     #include "xxx.h" 
     #ifndef YYY_H 
     #define YYY_H 1 
     #include "yyy.h" 
     #endif 
     #if TEST 
     int i; 
     #endif 

Here, the first token that does not belong to a preprocessing directive is again int , but the header stop point is the start of the #if block containing it. The PCH file reflects the inclusion of xxx.h and conditionally the definition of YYY_H and inclusion of yyy.h ; it does not contain the state produced by #if TEST .

A PCH file is produced only if the header stop point and the code preceding it (mainly, the header files themselves) meet the following requirements:

  • The header stop point must appear at file scope---it may not be within an unclosed scope established by a header file. For example, a PCH file is not created in this case:


             // xxx.h 
             class A { 
     
             // xxx.C 
             #include "xxx.h" 
             int i; }; 
    

    The header stop point may not be inside a declaration started within a header file, nor may it be part of a declaration list of a linkage specification. For example, in the following case the header stop point is int , but because it is not the start of a new declaration, no PCH file is created:


             // yyy.h 
             static 
     
             // yyy.C 
             #include "yyy.h" 
             int i; 
    

  • The header stop point cannot be inside a #if block or a #define started within a header file. The processing preceding the header stop must not have produced any errors. (Warnings and other diagnostics are generally not reproduced when the PCH file is reused.)
    No references to predefined macros __DATE__ or __TIME__ may have appeared. No use of the #line preprocessing directive may have appeared; #pragma no_pch (see <REFERENCE>(wys_ctrl_hdrs_sec)) must not have appeared. The code preceding the header stop point must have introduced a sufficient number of declarations to justify the overhead associated with precompiled headers.

When a precompiled header file is produced, it contains, in addition to the snapshot of the compiler state, some information that can be checked to determine under what circumstances it can be reused. This includes:

  • The compiler version, including the date and time the compiler was built
  • The current directory (that is, the directory in which the compilation is occurring)
  • The command-line options
  • The initial sequence of preprocessing directives from the primary source file, including #include directives
  • The date and time of the header files specified in #include directives

This information comprises the PCH prefix. The prefix information of a given source file can be compared to the prefix information of a PCH file to determine whether the latter is applicable to the current compilation.

As an illustration, consider two source files:


     // a.C 
     #include "xxx.h" 
     ...         // Start of code 
 
     // b.C 
     #include "xxx.h" 
     ...         // Start of code 

When a.C is compiled with -pch :

  1. A precompiled header file named a.pch is created.
  2. When b.C is compiled (or when a.C is recompiled), the prefix section of a.pch is read in for comparison with the current source file.

If the command-line options are identical, if xxx.h has not been modified, and so forth, then, instead of opening xxx.h and processing it line by line, the compiler reads in the rest of a.pch and thereby establishes the state for the rest of the compilation.

It may be that more than one PCH file is applicable to a given compilation. If so, the largest (that is,the one representing the most preprocessing directives from the primary source file) is used. For instance, consider a primary source file that begins as follows:


     #include "xxx.h" 
     #include "yyy.h" 
     #include "zzz.h" 

If there is one PCH file for xxx.h and a second for xxx.h and yyy.h , the latter will be selected (assuming both are applicable to the current compilation). Moreover, after the PCH file for the first two headers is read in and the third is compiled, a new PCH file for all three headers may be created.

When a precompiled header file is created, it takes the name of the primary source file, with the suffix replaced by .pch . Unless -pch_dir is specified, it is created in the current directory.

When a precompiled header file is created or used, a message such as the following is issued:


     "test.C": creating precompiled header file "test.pch" 

The user may suppress the message by using the command-line option -no_pch_messages .

In automatic mode (that is, when -pch is used) the compiler will deem a precompiled header file obsolete and delete it under either of the following circumstances:

  • The precompiled header file is based on at least one out-of-date header file but is otherwise applicable for the current compilation.
  • The precompiled header file has the same base name as the source file being compiled (for example, xxx.pch and xxx.C ) but is not applicable for the current compilation (for example, because of different command-line options).

This handles some common cases; the user must manage other PCH file clean up.

Only header files that were included in the original PCH file are checked for modification. If the user changes the structure of the header files, such that different files would be included now from when the PCH file was generated, without modifying at least one of the original header files that were included in the PCH file, the change would go undetected, and an out of date PCH file would be used.

For example, adding a prolog or epilog file to a directory that previously did not have one would not automatically result in a new PCH file being created.

Also, consider the following:


 cxx -Iinc1 -Iinc2 -pch foo.c 

Where foo.c includes the file foo.h . If file foo.h is found in directory inc2 when the PCH file is created, but a new foo.h is added to directory inc1 , thereby hiding the old foo.h in inc2 , a new PCH file would not be created.

It is the user's responsibility to remove any PCH files that may be out of date because of these kinds of changes.

6.2 Manual Precompiled Header Processing

Command-line option -create_pch file-name specifies that a precompiled header file of the specified name should be created.

Command-line option -use_pch file-name specifies that the indicated precompiled header file should be used for this compilation; if it is invalid (that is, if its prefix does not match the prefix for the current primary source file), a warning will be issued and the PCH file will not be used.

When either of these options is used in conjunction with -pch_dir , the indicated file name (which may be a path name) is tacked on to the directory name, unless the file name is an absolute path name.

The -create_pch , -use_pch , and -pch options may not be used together. If more than one of these options is specified, only the last one will apply. Nevertheless, most of the description of automatic PCH processing applies to one or the other of these modes---header stop points are determined the same way, PCH file applicability is determined the same way, and so forth.

6.3 Other Ways for Users To Control Precompiled Headers

The user can control and tune how precompiled headers are created and used in several ways:

  • #pragma hdrstop may be inserted in the primary source file at a point prior to the first token that does not belong to a preprocessing directive. This enables the user to specify where the set of header files that is subject to precompilation ends. For example,


             #include "xxx.h" 
             #include "yyy.h" 
             #pragma hdrstop 
             #include "zzz.h" 
    

    Here, the precompiled header file includes processing state for xxx.h and yyy.h but not zzz.h . (This is useful if the user decides that the information added by what follows the #pragma hdrstop does not justify the creation of another PCH file.)
  • #pragma no_pch may be used to prevent the generation of a pch file for a given source.
    Command-line option -pch_dir directory-name is used to specify the directory in which to search for or create a PCH file.

6.4 Performance Issues

The relative overhead incurred in writing out and reading back in a precompiled header file is quite small for reasonably large header files.

In general, it does not cost much to write a precompiled header file even if it does not end up being used, and if it is used, it almost always produces a significant decrease in compilation time.

Despite the faster recompilations, precompiled header processing is not likely to be justified for an arbitrary set of files with nonuniform initial sequences of preprocessing directives.

The greatest benefit occurs when a number of source files can share the same PCH file. The more sharing, the less disk space is consumed. With sharing, the disadvantage of large precompiled header files can be minimized, without giving up the advantage of a significant decrease in compilation times.

Consequently, to take full advantage of header file precompilation, users should expect to reorder the #include sections of their source files and to group #include directives within a commonly used header file.

Different environments and different projects will have different needs, but in general, users should be aware that making the best use of the precompiled header support will require some experimentation and probably some minor changes to source code.

6.5 Command-Line Options for Precompiled Headers

You can specify the following options for precompiled headers:

-create_pch file-name

If other conditions are satisfied, create a precompiled header file with the specified name. If -pch (automatic PCH mode) or -use_pch appears on the command line following this option, the last option is used. This option defines the macro __PCH_ENABLED .

-pch

Automatically use, create, or both, a precompiled header file. If -use_pch or -create_pch (manual PCH mode) appears on the command line following this option, the last option is used. This option defines the macro __PCH_ENABLED .

-pch_dir directory-name

The directory in which to search for, create, or both, a precompiled header file. You can use this option with automatic PCH mode ( -pch ) or manual PCH mode ( -create_pch or -use_pch ).

-pch_messages
-no_pch_messages

Enable or disable the display of a message indicating that a precompiled header file was created or used in the current compilation. The default is -pch_messages .

-use_pch file-name

Use a precompiled header file of the specified name as part of the current compilation. If -pch (automatic PCH mode) or -create_pch appears on the command line following this option, the last option is used. This option defines the macro __PCH_ENABLED .


Previous Next Contents Index
About PDF files: The PDF files on this site can be read online or printed using Adobe® Acrobat® Reader. If you do not have this software on your system, you may download it from Adobe's website.
Privacy statement Using this site means you accept its terms C++ support
© 2008 Hewlett-Packard Development Company, L.P.