In C++, you can use a template to declare a set of related:
- Classes (including structures)
- Functions
- Static data members of template classes
Reducing redundant template instantiations
Within
an application, you can instantiate the same template multiple times
with the same arguments or with different arguments. If you use the
same arguments, the repeated instantiations are redundant. These redundant
instantiations increase compilation time, increase the size of the
executable, and deliver no benefit.
There are several basic
approaches to the problem of redundant instantiations:
- Handling redundancy during linking
- The size increase of the final executable might be
small enough that it does not justify changing the way you compile
your program or modify the source file. Most linkers have some form
of garbage collection functionality. On Linux®,
the linker performs garbage collection well, especially when you use
the -qfuncsect option. If you use -qtmplinst=always or -qtmplinst=auto without
using -qtemplateregistry or -qtempinc,
no compile time management of redundant instantiations is done. In
this case, you can use the -qfuncsect option to
reduce the executable size. For details, see -qfuncsect in
the XL C/C++ Compiler
Reference.
- Controlling implicit instantiation in the source code
- Concentrating implicit instantiations of a specialization: Organize
your source code so that object files contain fewer instances of each
required instantiation and fewer unused instantiations. This
is the least usable approach, because you must know where each template
is defined, which instantiations are used, and where to declare an
explicit instantiation for each instantiation.
Using explicit instantiation declarations: With
the explicit instantiation declarations feature, you can suppress
the implicit instantiation of a template specialization or its members.
This helps reduce the collective size of the object files. It might
also reduce the size of the final executable if the suppressed symbol
definitions are meant to be found in a shared library, or if the system
linker is unable to always remove additional definitions of a symbol.
For more information, see Using explicit instantiation declarations (C++0x). Note: If
you want to control implicit instantiation in the source code, or
use explicit instantiation declarations, you can use the -qtmplinst=none or -qtmplinst=noinlines option
to prevent accidental implicit instantiations from occurring.
- Having the compiler store instantiation information in a registry
- Use the -qtemplateregistry compiler option.
Information about each template instantiation is stored in a template
registry. If the compiler is asked to instantiate the same template
again with the same arguments, it points to the instantiation in the
first object file instead. This approach is described in Using the -qtemplateregistry compiler option.
- Having the compiler store instantiations in a template include
directory
- Use the -qtempinc compiler option. If the template
definition and implementation files have the required structure, each
template instantiation is stored in a template include directory.
If the compiler is asked to instantiate the same template again with
the same arguments, it uses the stored version instead. The
source file created in the template include directory is compiled
during the link step recursively until all instantiations are done. This
approach is described in Using the -qtempinc compiler option.
Notes: - The -qtempinc and -qtemplateregistry compiler
options are mutually exclusive.
- -qtemplateregistry is a better approach
than -qtempinc for the following reasons:
- -qtemplateregistry provides better benefits
than -qtempinc.
- -qtemplateregistry does not require modifications
to the header files.
The compiler generates code for an implicit
instantiation unless one of the following conditions is true:
- You use either -qtmplinst=none or -qtmplinst=noinlines.
- You use -qtmplinst=auto, which is the default
suboption of -qtmplinst with -qnotemplateregistry.
- You use -qtmplinst=auto with -qtempinc and
the template source that is organized to use -qtempinc.
An explicit instantiation declaration for that instantiation
is in the current translation unit.