United States |
Previous | Contents | Index |
Using precompiled header (PCH) files can dramatically reduce compilation time in environments where:
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.
Because, however, PCH files are typically large (from a minimum of 250 KB to several megabytes or more), as many sources as possible should share the same PCH files. The performance gain is thereby achieved at the smallest cost in disk storage.
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.5). 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 Section 6.3). 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:
// xxx.h class A { // xxx.C #include "xxx.h" int i; }; |
// yyy.h static // yyy.C #include "yyy.h" int i; |
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:
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:
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:
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:
#include "xxx.h" #include "yyy.h" #pragma hdrstop #include "zzz.h" |
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. But because header files can be large (from a minimum of about 250K bytes to several megabytes or more), you probably want to keep the number to a minimum.
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 (-use_pch or -pch) or manual PCH mode -create_pch or -use_pch.-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.
-no_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 |
|