United States    
COMPAQ STORE | PRODUCTS |
SERVICES | SUPPORT | CONTACT US | SEARCH
cxxtitle.gif (12116 bytes)
Compaq C++

Compaq C++
Using Compaq C++ for Tru64 UNIX Systems


Previous Contents Index

5.2 Automatic Instantiation Specifics

This section describes automatic instantiation in detail, beginning with an overview of the instantiation process.

5.2.1 Overview of the Instantiation Process

The process of automatically instantiating a template has the following steps:

  1. The user issues a cxx command to compile or link specified files.
    If the user invokes the cxx command specifying no source files but only object, archive, or shared library files, the process skips ahead to step 5. Remember that if you explicitly specified the repository path name during compilation, you must also specify the repository path name on the cxx command at link time.
  2. Compaq C++ sets the current repository. If the user specifies the -ptr option and the specified repository does not exist, Compaq C++ creates the user-specified repository. Otherwise, Compaq C++ checks for the existence of a repository named ./cxx_repository. If ./cxx_repository does not exist, Compaq C++ creates one in your current working directory.
  3. Compaq C++ invokes the compiler in default mode. The compiler uses the template declaration file, the template definition file, and the top-level header files of your application to create an instantiation source file for each function template or class template used within the source program. If you use the -pts switch, a separate instantiation source file is created for each member function template or static data member template used within the source program.
    If an instantiation source file already exists in the repository, the compiler checks whether this file is current with regard to the corresponding header files and the command-line options. If the instantiation source file is out of date, the compiler re-creates it.
  4. If you specified the -c option on the command line, Compaq C++ has completed the compilation and returns control to the user.
  5. Compaq C++ invokes ld to perform a prelink, to partially link those object files that are generated from the C++ or C source files specified on the command line, plus any archived or shared library files. The linker performs symbol processing only; it does not create an executable.
  6. For each unresolved symbol reported by the linker in step 5, Compaq C++ searches either the default or the user-specified repositories for the corresponding instantiation object file. The writeable repository is searched first, followed by any read-only repositories specified on the cxx command.
  7. For each instantiation object file found in the writeable repository, Compaq C++ checks whether that file is up to date with regard to the instantiation source file. For class templates, Compaq C++ also checks the contents of the instantiation request file to see whether it specifies all the members that have been requested thus far during the prelink phase. If the instantiation object file is found to be out of date or the instantiation request file is missing any requests, Compaq C++ invokes the compiler in template request mode to generate the instantiation. In template request mode, the compiler generates code only for the function template or class template members specified in the instantiation request file. The resulting object file is placed in the writeable repository and added to the link command in step 5. If the instantiation object file is up to date, Compaq C++ simply adds the file to the link command in step 5.
    For each instantiation object file found in a read-only repository, Compaq C++ performs no dependency checking except for class templates: Compaq C++ verifies that the instantiation request file specifies all the members that have been requested thus far during the prelink phase. If the instantiation request file is missing any requests, Compaq C++ ignores the object file. Otherwise Compaq C++ adds the object file to the link command in step 5.
    If no instantiation object file is found, or if a read-only repository object was found but is missing requests, Compaq C++ creates an instantiation object file by compiling (in template request mode) the instantiation source file located in the writeable repository. The resulting object is placed in the writeable repository and added to the link command in step 5.
  8. Compaq C++ repeats steps 5 through 7 until either no unresolved symbols remain or no object files can be found within the repositories that correspond to the unresolved symbols.
  9. Compaq C++ invokes ld with the modified link command to perform the final link.

5.2.2 Command-Line Options Specific to Templates

The following cxx command-line options are specific to automatic instantiation of templates:
-nopragma_template Directs the compiler to ignore any #pragma define_template directives. This option is provided for users who want to quickly migrate to automatic instantiation without having to remove all the pragma directives from their code base.
-nopt Directs the compiler to not automatically instantiate templates.
-pt Directs the compiler to automatically instantiate templates. Each function template is placed in its own instantiation file, and member functions and static data members of each class template are grouped into one instantiation file. This option is the default.
-ptr pathname Specifies a repository, with ./cxx_repository as the default. If you specify several repositories, only the first is writable, and the rest are read only.

Specifying this option at link time enables Compaq C++ to recognize and use the various template instantiations within the specified repository. If you use this option, make sure that the repository specified at compile time is the same one specified at link time.

-pts Directs Compaq C++ to automatically instantiate needed templates. Each member function or static data member is instantiated in its own separate file.
-ptsuf" list" Specifies a list of file name suffixes that are valid for template definition files. Items in the list must be separated by commas and each suffix preceded by a period. A suffix may have no more than eight characters excluding the beginning period. The default is ".cxx,.CXX,.C,.cc,.CC,.cpp,.c" .
-ptv Turns on verbose or verify mode to display each phase of instantiation as it occurs. This option is useful as a debugging aid; see Section 5.2.9.1.3.
-use_ld_input Directs Compaq C++ to record the names of requested automatic template instantiation object files in a linker options file in the writable repository.

Compaq C++ then adds the linker options file to the ld command line using the -input file linker command line option.

The default behavior is to add the instantiation file names directly to the ld command line.

You can use the -use_ld_input option to reduce long ld command lines that cause linking to fail because of "Arg list too long" errors.

5.2.3 Repositories

Between distinct compilations and linking, Compaq C++ stores the necessary template instantiation information in a repository. You can specify a path name for the repository at both compile time and link time using the -ptr command-line option. If you specify multiple path names, the first becomes the writeable repository and the rest are designated as read-only repositories. A repository is implemented as a UNIX directory that can contain the following:

For example, given an instantiation request for the member function element(T) of template class Vector<int>, the repository would contain the following files:
File Description
Vector__Ti.cmd Dependency file containing the command-line options
Vector__Ti.cxx Instantiation source file
Vector__Ti.o Instantiation object file
Vector__Ti.o.d Dependency file containing the list of header files
Vector__Ti.req Instantiation request file

Repository Permissions

The default repository acquires the same permissions as the directory in which it resides, and therefore has the same access as the parent directory. Any files created in the repository reflect this access.

5.2.4 Template Declaration File

This file contains the declaration of the template; include it in your application using the #include syntax.

The following is an example of a declaration file, AAA.h, containing a class template:


#ifndef AAA_H 
#define AAA_H 
template <class T> class AAA 
{ 
    T x; 
    int y; 
public: 
    void f(void); 
    void g(T&); 
}; 
#endif 

The following is an example of a forward declaration for a function template:


template <class T> void sort (T*, int n); 

A template declaration file should include the header files it needs for the types it uses. It should not include header files for types used as template arguments or the definition of the template itself because Compaq C++ handles these automatically.

5.2.5 Template Definition File

This file contains the template implementation. Given the previous declaration file example, AAA.h, the corresponding template definition file, AAA.cxx, would contain code fragments as follows:


template <class T> void AAA <T>::f(void) { /* ...*/ } 
   .
   .
   .
template <class T> void AAA <T>::g(T&) { /* ...*/ } 

Template definition files are treated like header files. They should contain only definitions of function, member function, or static data member templates. To avoid external linkages leading to unresolved symbols, Compaq C++ ignores any definitions of functions or data items found in template definition files.

If you include the corresponding declaration file in the template definition file, or include the header files that declare any template argument types, you should guard against multiple inclusion. If a definition file does not exist for each corresponding declaration file, you must write a name-mapping file to override the standard convention (see Section 5.2.6). Otherwise, Compaq C++ does not include the definition file in the instantiation source file.

5.2.6 Name-Mapping File

The name-mapping file is supplied by the user and must be named Template.map. The file is in the repository directory and contains information the compiler uses to automatically instantiate templates; it supplements template information found in the source code and in header files.

A name-mapping file consists of the following entries:

Compaq C++ permits only one definition entry per template name. Thus, if the same name is used to define three different templates, each within its own file, you must list all three files in a single definition entry for that name.

Example 1

Consider the following template function:


template <class T> void sort( T *p ) {} 

The following is a valid name-mapping file definition entry:


definition sort in "sort_impl.cxx"; 

With this definition, the compiler expects to find the body of function template sort() in the source file sort_impl.cxx.

Example 2

Consider the following template member function:


   template <class T> class List { 
   public: 
        void add_item(T new_item); 
   /* ...*/ 
   }; 

The following is a valid name-mapping file definition entry:


   definition add_item in "List_funcs.cxx"; 

This definition instructs the compiler to find the body of the member function template add_item() in the source file List_funcs.cxx.

Presumably the source file List_funcs.cxx contains the following code:


#include "List.h" 
template <class T> void List<T>::add_item(T new_item){} 

Automatic instantiation makes including List.h more than once a possibility. To guard against this happening, you should enclose the code in include guards, as in the following example:


#ifndef List_H 
#define List_H 
... // code for List.h 
#endif 

Example 3

Consider the following overloaded template member function:


//List.h 
#ifndef List_H 
#define List_H 
template <class T> class List { 
Public: 
   List(); 
   List(const List& l); 
   /* ...*/ 
}; 
#endif 
 
//List.cxx 
#include "List.h" 
template <class T> List<T>::List(){} 
 
//List_copy.cxx 
#include "List.h" 
template <class T> List<T>::List(const List& l){} 

The following is a valid name-mapping file definition entry:


definition List in "List.cxx", "List_copy.cxx"; 

5.2.7 Instantiation Source File

By default, Compaq C++ creates one instantiation source file for each function template instantiation request, and one for each class template instantiation request. The instantiation source file includes all the headers needed to correctly instantiate a template. The order of inclusion is as follows (no file is included more than once):

  1. Template declaration file and top-level header files, in the order they appeared in the compilation unit requesting the instantiation.
  2. Template definition files.

For example, consider the following name-mapping file:


# Stack Implementation 
definition Stack in "Stack_Impl.cxx"; 

With an external unresolved symbol, Stack<C>::push(C), where class C is defined in the header file Cdef.h, the result would be the following instantiation source file:


#include "Cdef.h" 
#include "Stack.h" 
#include "Stack_Impl.cxx" 
 
typedef Stack<C> __dummy_; 

5.2.7.1 Template Definition File Lookup

Compaq C++ matches each instantiation request with the corresponding template definition file to create the instantiation source file. The name of this source file must be similar to that of the template declaration file. Compaq C++ uses the following lookup order:

  1. Search the user-provided name-mapping file (Template.map, in the repository list) for the name of the function, member function, or static data member template.
  2. If the #include name for the header file containing the template declaration is specified with an absolute path name, look only in the directory specified by the path name.
  3. If the #include name for the header file containing the template declaration is specified with a relative path name, take the following action:
    1. If the header file name is specified with double quotation marks (" ") and the -nocurrent_include option was not specified, append the relative path name to the directory containing the source file, and search for files with the appropriate suffixes.
    2. Otherwise, append the relative path name to all the -I directories and look in those resulting directories for files with the appropriate suffixes.

    For source files, the appropriate suffixes are, in order of preference: .cxx, .CXX, .C, .cc, .CC, .cpp, and .c, or as defined by the -ptsuf option.
    Compaq C++ ignores any file extension that does not begin with a dot (.) or that has more than eight total characters in the extension.

5.2.8 Dependency Management

When a program makes a template instantiation request, Compaq C++ avoids creating and compiling a new instantiation source file if existing source and object files can be reused.

For each instantiation request, when Compaq C++ finds a corresponding instantiation source file or object file in the writeable repository, the following checks are performed:

  1. Compaq C++ compares the command-line options used to compile the existing instantiation source file with the current command-line options. If the options do not match, then Compaq C++ creates and compiles a new instantiation source file.
  2. The creation date of the instantiation object file is compared to the modification date of each header file included by the instantiation source file. If any header files have changed since the object file was created, then Compaq C++ creates and compiles a new instantiation source file.
  3. For class templates, Compaq C++ examines the contents of the instantiation request file to determine if any requests are missing. If the instantiation request file is not complete, Compaq C++ modifies the file and then recompiles the instantiation source file.

5.2.9 Building Libraries and Applications That Use Templates

When you build libraries and applications using manual instantiation, you face the tedious tasks of ensuring that all necessary templates are instantiated and of determining where each template instantiation is generated to avoid duplicates. The advantage of this method is that you have complete control over template instantiations; however using this approach can be time-consuming.

Automatic template instantiation performs these manual tasks for you if your build procedure and sources are properly set up. The procedure for building libraries and applications using automatic template instantiation differs somewhat from the procedure for manual instantiation. This section discusses the basic issues when using automatic template instantiation; it also provides suggestions and examples for resolving these issues.

See Section 3.4 for suggestions on organizing your sources.

5.2.9.1 Building a Standalone Library

Library vendors obviously need to provide a standalone library to their customers. With respect to templates, standalone means that the library contains:

In addition to library vendors, developers of large applications may want to divide their application into one or more standalone libraries to facilitate building. Creating a single library is straightforward. However, creating multiple libraries is more difficult if the libraries use the same template instantiations.


Previous Next Contents Index
  

1.800.AT.COMPAQ

privacy and legal statement