C++ User's Guide

Chapter 4 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.

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.

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. The CCadmin -clean command (formerly ptclean) clears out all instantiations and associated data. Instantiations are recreated only when needed.

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.

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.

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 the ar command. For example:


%demo CC -xar -o libmain.a a.o b.o c.o

See Chapter 6, Building Libraries for more information.

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:

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. You can use static instance linkage only with the definitions-included template organization. The compiler does not search for definitions. (See C++ Programming Guide.)

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.

Global instances can be used only with the definitions-included template organization. The compiler does not search for definitions.

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.

You can use explicit instance linkage only with the definitions-included template organization. The compiler does not search for definitions.

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.

Specify semi-explicit instances with the -instances=semiexplicit option.

You can use semi-explicit instance linkage only with the definitions-included template organization. The compiler does not search for definitions.

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.

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 the SUNWS_CACHE_NAME environment variable.

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,


demo% CC -o sub/a.o a.cc

this command line:

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.

You can specify an alternate repository location with the -ptrdirectory option.

Reading From Multiple Template Repositories

The compiler reads from the template repositories corresponding to the object files that it reads. That is,


demo% CC sub1/a.o sub2/b.o

this command line:

reads from ./sub1/SunWS_cache and ./sub2/SunWS_cache, and, if necessary, writes to ./SunWS_cache.

Do not specify multiple repositories by giving multiple -ptr options. You can only use -ptr to specify a single repository location.

Sharing Template Repositories

Do not share template repositories among multiple programs or libraries. That is, the following approach is not supported and can result in inconsistent results and random link errors.


demo% CC a.cc
demo% CC b.cc

In practice, this means you must either compile separate programs (or libraries) in separate directories, or clean out the template repository between each program or library compilation.

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.

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 current include path. For example, if the template function foo() is located in foo.h, the matching template definition file should be named foo.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 normal include directories or in the same directory as its matching header file.

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 -ptidirectory. Multiple -pti flags define multiple search directories--that is, a search path. If you use -ptidirectory, the compiler looks for template definition files on this path and ignores the -I flag. Since the -ptidirectory flag complicates the search rules for source files, use the -I option instead of the -ptidirectory option.

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 name DEBUG, the database tracks this. If you omit this flag on a subsequent compile, the compiler reinstantiates those templates on which this dependency is set.

Compile-Time Instantiation

Instantiation is the process by which a C++ compiler creates a usable function or object from a template. The Sun C++ 5.0 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:

Templates can be instantiated multiple times if source files reside in different directories or if you use libraries with template symbols.