DIGITAL C++
Using DIGITAL C++ for DIGITAL UNIX Systems


Previous Contents Index

5.7 Compatibility with Earlier Versions of DIGITAL C++

The automatic template instantiation model is new with DIGITAL C++ Version 6.0, and is not directly compatible with previous DIGITAL C++ automatic template instantiation. When linking applications using Version 6.0, instantiations may not be resolved from existing Version 5.n repositories. Note that the compiler invoked when you use the -oldcxx option is a Version 5.n compiler. Where possible, it is safest to start fresh with an empty repository, and create the required instantiations by compiling all source files. If this is not possible, there are some strategies that can be used to link mixed generation instantiations.

If you used both Version 6.0 and Version 5.n to build applications, DIGITAL strongly recommends that you use different repositories to contain automatic template instantiations for Version 6.0 and Version 5.n compilations. Note that the default repository name is the same for Version 6.0 as for prior versions. Thus, if you use Version 6.0 with older DIGITAL C++ compilers, you should do compilations in a different directory for each compiler or explicitly specify a different repository for each using the -ptr option.

5.7.1 Linking with Version 5.n Instantiations

When linking applications using Version 6.0 against instantiations created with Version 5.n, it is necessary to complete the Version 5.n instantiation process, to create instantiation object files. This can be done with the -oldcxx and -Hf command-line options when linking. If old_repository is a Version 5.n repository then you would create the Version 5.n instantiation object files by using:


 
 cxx -oldcxx -Hf  -ptr old_repository <Version 5.n object files> 
 

<Version 5.n object files> are the object files that were created using the Version 5.n compiler; old_repository now contains the instantiation object files. Create a library of these object files as follows:


 ar r lib_old_repository.a old_repository/*.o 

When linking using Version 6.0, specify lib_old_repository.a after all of the Version 5.n object files that are being linked.

5.8 Linking Version 5.n Applications Against Version 6.0 Repositories

In a similar way, you can create a library of Version 6.0 instantiation object files to link into a Version 5.n application being linked using DEC C++ Version 5.n. If new_repository is the Version 6.0 repository, then a library of the instantiations would be created by:


 ar r lib_new_repository.a new_repository/*.o 

When linking using Version 5.n, specify lib_new_repository.a after all of the Version 6.0 object files that are being linked.


Chapter 6
Precompiled Headers

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:

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, a precompiled header file named a.pch is created. Then, 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:

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

Note that 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:

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. 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. Rather, 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-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