Compaq C++ User Documentation — C++ 6.2
| United States |
|
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:
- 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. - 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.
- 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. - If you specified the -c option on the command line, Compaq C++ has completed the compilation and returns control to the user.
- 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.
- 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.
- 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. - 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.
- 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:
- Name-mapping file, a text file that directs the compiler to the template definition files created by the user. The default name is Template.map. See Section 5.2.6 for instructions on how to create and use this file.
- Instantiation source files that, when compiled in template request mode, generate the instantiation. These files have the extension .cxx (see Section 5.2.7).
- Dependency files that contain information regarding the header files included by a particular instantiation and the command-line options used to generate the instantiation. The files have the extension .o.d and .cmd respectively (see Section 5.2.8).
- Instantiation object files that contain template instantiations. These files have the extension .o.
- Instantiation request files for class templates that contain the list of member instantiations generated in the corresponding instantiation object file. These files have the extension .req.
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 |
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:
- Comment entries
These start with a sharp sign (#) followed by comment text. - Definition entries
These tell the compiler where to find a function template body, a member function template body, or a static member initializer. A definition entry has the following format:
definition name in "filename" [, "filename"...];name
A simple name to identify the template to the compiler. Qualified names are unnecessary and not allowed. Parentheses, return types, and parameter lists are also not allowed.filename
The path name of the file containing the template definition. Each file listed will be included in the resulting instantiation source file.
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.
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.
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 |
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):
- Template declaration file and top-level header files, in the order they appeared in the compilation unit requesting the instantiation.
- 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:
- 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.
- 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.
- If the #include name for the header
file containing the template declaration is specified with a relative
path name, take the following action:
- 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.
- 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:
- 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.
- 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.
- 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:
- All the template instantiations it uses
- Any additional template instantiations that the vendor wants to provide to the customer
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 |
|
|
privacy and legal statement
