C++ User's Guide |
Compiling Templates
Template compilation requires the C++ compiler to do more than traditional UNIX compilers have done. The C++ compiler must generate object code for template instances on an as-needed basis. It might share template instances among separate compilations using a template repository. It might accept some template compilation options. It must locate template definitions in separate source files and maintain consistency between template instances and mainline code.
4.1 Verbose Compilation
When given the flag
--verbose=template
, the C++ compiler notifies you of significant events during template compilation. Conversely, the compiler does not notify you when given the default,--verbose=no%template
. The+w
option might give other indications of potential problems when template instantiation occurs.4.2 Template Commands
The
CCadmin
(1) command administers the template repository. For example, changes in your program can render some instantiations superfluous, thus wasting storage space. TheCCadmin
-clean
command (formerlyptclean
) clears out all instantiations and associated data. Instantiations are recreated only when needed.4.3 Template Instance Placement and Linkage
You can instruct the compiler to use one of five instance placement and linkage methods: external, static, global, explicit, and semi-explicit.
- External instances are suitable for all development and provide the best overall template compilation.
- Static instances are suitable for very small programs or debugging and have restricted uses.
- Global instances are suitable for some library construction.
- Explicit instances are suitable for some carefully controlled application compilation environments.
- Semi-explicit instances require slightly less controlled compilation environments but produce larger object files and have restricted uses.
You should use the external instances method, which is the default, unless there is a very good reason to do otherwise. See the C++ Programming Guide for further information.
4.3.1 External Instances
With the external instances method, all instances are placed within the template repository. The compiler ensures that exactly one consistent template instance exists; instances are neither undefined nor multiply defined. Templates are reinstantiated only when necessary.
Template instances receive global linkage in the repository. Instances are referenced from the current compilation unit with external linkage.
Specify external linkage with the
--instances=extern
option (the default option).Because instances are stored within the template repository, you must use the
CC
command to link C++ objects that use external instances into programs.If you wish to create a library that contains all template instances that it uses, use the
CC
command with the--xar
option. Do not use thear
command. For example:
example%CC -xar -o libmain.a a.o b.o c.o
See Chapter 6 for more information.
4.3.2 Static Instances
With the static instances method, all instances are placed within the current compilation unit. As a consequence, templates are reinstantiated during each recompilation; instances are not saved to the template repository.
Instances receive static linkage. These instances will not be visible or usable outside the current compilation unit. As a result, templates might have identical instantiations in several object files. This has the following undesirable consequences:
- Multiple instances produce unnecessarily large programs. (Static instance linkage is therefore suitable only for small programs, where templates are unlikely to be multiply instantiated.)
- Templates that contain static variables have many copies of the variable, and this is an unavoidable violation of the C++ standard. Therefore, use of static instances is not supported with static variables within templates.
Compilation is potentially faster with static instances, so this method might also be suitable during Fix-and-Continue debugging. (See Debugging a Program With
dbx
.)Specify static instance linkage with the
--instances=static
compiler option.4.3.3 Global Instances
With the global instances method, all instances are placed within the current compilation unit. As a consequence, templates are reinstantiated during each recompilation; they are not saved to the template repository.
Template instances receive global linkage. These instances are visible and usable outside the current compilation unit. As a consequence, instantiation in more than one compilation unit results in multiple symbol definition errors during linking. The global instances method is therefore suitable only when you know that instances will not be repeated.
Specify global instances with the
--instances=global
option.4.3.4 Explicit Instances
In the explicit instances method, instances are generated only for templates that are explicitly instantiated. Implicit instantiations are not satisfied. Instances are placed within the current compilation unit. As a consequence, templates are reinstantiated during each recompilation; they are not saved to the template repository.
Template instances receive global linkage. These instances are visible and usable outside the current compilation unit. Multiple explicit instantiations within a program result in multiple symbol definition errors during linking. The explicit instances method is therefore suitable only when you know that instances are not repeated, such as when you construct libraries with explicit instantiation.
Specify explicit instances with the
--instances=explicit
option.4.3.5 Semi-Explicit Instances
When you use the semi-explicit instances method, instances are generated only for templates that are explicitly instantiated or implicitly instantiated within the body of a template. Implicit instantiations in the mainline code are not satisfied. Instances are placed within the current compilation unit. As a consequence, templates are reinstantiated during each recompilation; they are not saved to the template repository.
Explicit instances receive global linkage. These instances are visible and usable outside the current compilation unit. Multiple explicit instantiations within a program result in multiple symbol definition errors during linking.The semi-explicit instances method is therefore suitable only when you know that explicit instances will not be repeated, such as when you construct libraries with explicit instantiation.
Implicit instances used from within the bodies of explicit instances receive static linkage. These instances are not visible outside the current compilation unit. As a result, templates can have identical instantiations in several object files. This has two undesirable consequences:
- Multiple instances produce unnecessarily large programs. (Semi-explicit instance linkage is therefore suitable only for programs where template bodies do not cause multiple instantiations.)
- Templates that contain static variables have many copies of the variable; this is an unavoidable violation of the C++ standard. Therefore, use of the semi-explicit instances method is not supported with static variables within templates.
Specify semi-explicit instances with the
--instances=semiexplicit
option.4.4 The Template Repository
The template repository stores template instances between separate compilations so that template instances are compiled only when necessary. The template repository contains all nonsource files needed for template instantiation when using the external instances method. The repository is not used for other kinds of instances.
4.4.1 Repository Structure
The template repository is contained, by default, within the Sun WorkShop cache directory (
SunWS_cache
). The Sun WorkShop cache directory is contained within the directory in which the output files will be placed. You can change the name of the cache directory by setting theSUNWS_CACHE_NAME
environment variable.4.4.2 Writing to the Template Repository
When the compiler must store template instances, it stores them within the template repository corresponding to the output file. That is,
this command line:
example%CC -o sub/a.o a.cc
writes the object file to
./sub/a.o
and writes template instances into the repository contained within./sub/SunWS_cache
. If the cache directory does not exist, and the compiler needs to instantiate a template, the directory is created for you.4.4.3 Reading From Multiple Template Repositories
The compiler reads from the template repositories corresponding to the object files that it reads. That is,
this command line:
example%CC sub1/a.o sub2/b.o
reads from
./sub1/SunWS_cache
and./sub2/SunWS_cache
, and, if necessary, writes to./SunWS_cache
.4.4.4 Sharing Template Repositories
Templates that are within a repository must not violate the one-definition rule of the ISO/ANSI C++ standard. That is, a template must have the same source in all uses of the template. Violating this rule produces undefined behavior. The simplest, though most conservative, way to ensure the rule is not violated is to build only one program or library within any one directory.
4.5 Template Definition Searching
When you use the definitions-separate template organization, template definitions are not available in the current compilation unit, and the compiler must search for the definition. This section describes how the compiler locates the definition.
Definition searching is somewhat complex and prone to error. Therefore, you should use the definitions-included template file organization if possible. Doing so helps you avoid definition searching altogether. See the C++ Programming Guide.
Note If you use the-template=no%extdef
option, the compiler will not search for separate source files.
4.5.1 Source File Location Conventions
Without the specific directions provided with an options file, the compiler uses a
Cfront
-style method to locate template definition files. This method requires that the template definition file contain the same base name as the template declaration file. This method also requires that the template definition file be on the currentinclude
path. For example, if the template functionfoo()
is located infoo.h
, the matching template definition file should be namedfoo.cc
or some other recognizable source-file extension (.C
,.c
,.cc
,.cpp
, or.cxx
). The template definition file must be located in one of the normalinclude
directories or in the same directory as its matching header file.4.5.2 Definitions Search Path
As an alternative to the normal search path set with
-I
, you can specify a search directory for template definition files with the option-pti
directory. Multiple-pti
flags define multiple search directories--that is, a search path. If you use-pti
directory, the compiler looks for template definition files on this path and ignores the-I
flag. Since the-pti
directory flag complicates the search rules for source files, use the-I
option instead of the-pti
directory option.4.6 Template Instance Automatic Consistency
The template repository manager ensures that the states of the instances in the repository are consistent and up-to-date with your source files.
For example, if your source files are compiled with the
-g
option (debugging on), the files you need from the database are also compiled with-g
.In addition, the template repository tracks changes in your compilation. For example, if you have the
--DDEBUG
flag set to define the nameDEBUG
, the database tracks this. If you omit this flag on a subsequent compile, the compiler reinstantiates those templates on which this dependency is set.4.7 Compile-Time Instantiation
Instantiation is the process by which a C++ compiler creates a usable function or object from a template. The Sun WorkShop 6 C++ compiler uses compile-time instantiation, which forces instantiations to occur when the reference to the template is being compiled.
The advantages of compile-time instantiation are:
- Debugging is much easier--error messages occur within context, allowing the compiler to give a complete traceback to the point of reference.
- Template instantiations are always up-to-date.
- The overall compilation time, including the link phase, is reduced.
Templates can be instantiated multiple times if source files reside in different directories or if you use libraries with template symbols.
4.8 Template Options File
The template options file is a user-provided optional file that contains the options needed to locate template definitions and to control instance recompilation. In addition, the options file provides features for controlling template specialization and explicit instantiation. However, because the C++ compiler now supports the syntax required to declare specializations and explicit instantiation in the source code, you should not use these features.
Note The template options file may not be supported in future releases of the C++ compiler.
The options file is named
CC_tmpl_opt
and resides within theSunWS_config
directory. This directory name may be changed using theSUNWS_CONFIG_NAME
environment variable.The options file is an ASCII text file containing a number of entries. An entry consists of a keyword followed by expected text and terminated with a semicolon (;). Entries can span multiple lines, although the keywords cannot be split.
4.8.1 Comments
Comments start with a
#
character and extend to the end of the line. Text within a comment is ignored.
# Comment text is ignored until the end of the line.4.8.2 Includes
You may share options files among several template databases by including the options files. This facility is particularly useful when building libraries containing templates. During processing, the specified options file is textually included in the current options file. You can have more than one
include
statement and place them anywhere in the options file. The options files can also be nested.
include "options-file";4.8.3 Source File Extensions
You can specify different source file extensions for the compiler to search for when the compiler is using its default
Cfront
-style source-file-locator mechanism. The format is:
extensions "ext-list";The ext-list is a list of extensions for valid source files in a space-separated format such as:
extensions ".CC .c .cc .cpp";In the absence of this entry from the options file, the valid extensions for which the compiler searches are
.cc
,.c
,.cpp
,.C,
and.cxx
.4.8.4 Definition Source Locations
You can explicitly specify the locations of definition source files using the definition option file entry. Use the definition entry when the template declaration and definition file names do not follow the standard
Cfront
-style conventions. The entry syntax is:
definition name in "file-1",[ "file-2" ..., "file-n"] [nocheck "options"];The name field indicates the template for which the option entry is valid. Only one definition entry per name is allowed. That name must be a simple name; qualified names are not allowed. Parentheses, return types, and parameter lists are not allowed. Regardless of the return type or parameters, only the name itself counts. As a consequence, a definition entry may apply to several (possibly overloaded) templates.
The "file-n" list field specifies the files that contain the template definitions. The search for the files uses the definition search path. The file names must be enclosed in quotes (" "). Multiple files are available because the simple template name may refer to different templates defined in different files, or because a single template may have definitions in multiple files. For example, if
func
is defined in three files, then those three files must be listed in the definition entry.The nocheck field is described at the end of this section.
In the following example, the compiler locates the template function
foo
infoo.cc
, and instantiates it. In this case, the definition entry is redundant with the default search.
CODE EXAMPLE 4-1 Redundant Definition Entry foo.cc
template <class T> T foo( T t ) { }CC_tmpl_opt
definition foo in "foo.cc";
The following example shows the definition of static data members and the use of simple names.
The name provided for the definition of
fooref
is a simple name and not a qualified name (such asfoo::fooref)
. The reason for the definition entry is that the file name is not foo.cc (or some other recognizable extension) and cannot be located using the defaultCfront
-style search rules.The following example shows the definition of a template member function. As the example shows, member functions are handled exactly like static member initializers.
The following example shows the definition of template functions in two different source files.
In this example, the compiler must be able to find both of the definitions of the overloaded function
func()
. The definition entry tells the compiler where to find the appropriate function definitions.Sometimes recompiling is unnecessary when certain compilation flags change. You can avoid unnecessary recompilation using the
nocheck
field of the definition option file entry, which tells the compiler and template database manager to ignore certain options when checking dependencies. If you do not want the compiler to reinstantiate a template function because of the addition or deletion of a specific command-line flag, use thenocheck
flag. The entry syntax is:
definition name in "file-1"[, "file-2" ..., "file-n"] [nocheck "options"];The options must be enclosed in quotes (" ").
In the following example, the compiler locates the template function
foo
infoo.cc
, and instantiates it. If a reinstantiation check is later required, the compiler will ignore the-g
option.
CODE EXAMPLE 4-5 nocheck
Optionfoo.cc
template <class T> T foo( T t ) {}CC_tmpl_opt
definition foo in "foo.cc" nocheck "-g";
4.8.5 Template Specialization Entries
Until recently, the C++ language provided no mechanism for specializing templates, so each compiler provided its own mechanism. This section describes the specialization of templates using the mechanism of previous versions of the C++ compilers. This mechanism is only supported in compatibility mode (
-compat
[=4
]).The
special
entry tells the compiler that a given function is a specialization and should not be instantiated when the compiler encounters the function. When using the compile-time instantiation method, usespecial
entries in the options file to preregister the specializations. The syntax is:
special declaration;The declaration is a legal C++-style declaration without return types. For example:
CODE EXAMPLE 4-6 special
Entryfoo.h
template <class T> T foo( T t ) { };main.cc
#include "foo.h"CC_tmpl_opt
special foo(int);
The preceding options file informs the compiler that the template function
foo()
should not be instantiated for the typeint
, and that a specialized version is provided by the user. Without that entry in the options file, the function may be instantiated unnecessarily, resulting in errors:
In the preceding example, when the compiler compiles
main.cc
, the specialized version offoo
is correctly used because the compiler has seen its definition. Whenfile.cc
is compiled, however, the compiler instantiates its own version offoo
because it doesn't knowfoo
exists inmain.cc
. In most cases, this process results in a multiply-defined symbol during the link, but in some cases (especially libraries), the wrong function may be used, resulting in runtime errors. If you use specialized versions of a function, you should register those specializations.The
special
entries can be overloaded, as in this example:
To specialize a template class, include the template arguments in the special entry:
If a template class member is a static member, you must include the keyword
static
in your specialization entry:
Sun Microsystems, Inc. Copyright information. All rights reserved. Feedback |
Library | Contents | Previous | Next | Index |