gcc: Template Instantiation

1 
1 7.5 Where's the Template?
1 =========================
1 
1 C++ templates were the first language feature to require more
1 intelligence from the environment than was traditionally found on a UNIX
1 system.  Somehow the compiler and linker have to make sure that each
1 template instance occurs exactly once in the executable if it is needed,
1 and not at all otherwise.  There are two basic approaches to this
1 problem, which are referred to as the Borland model and the Cfront
1 model.
1 
1 Borland model
1      Borland C++ solved the template instantiation problem by adding the
1      code equivalent of common blocks to their linker; the compiler
1      emits template instances in each translation unit that uses them,
1      and the linker collapses them together.  The advantage of this
1      model is that the linker only has to consider the object files
1      themselves; there is no external complexity to worry about.  The
1      disadvantage is that compilation time is increased because the
1      template code is being compiled repeatedly.  Code written for this
1      model tends to include definitions of all templates in the header
1      file, since they must be seen to be instantiated.
1 
1 Cfront model
1      The AT&T C++ translator, Cfront, solved the template instantiation
1      problem by creating the notion of a template repository, an
1      automatically maintained place where template instances are stored.
1      A more modern version of the repository works as follows: As
1      individual object files are built, the compiler places any template
1      definitions and instantiations encountered in the repository.  At
1      link time, the link wrapper adds in the objects in the repository
1      and compiles any needed instances that were not previously emitted.
1      The advantages of this model are more optimal compilation speed and
1      the ability to use the system linker; to implement the Borland
1      model a compiler vendor also needs to replace the linker.  The
1      disadvantages are vastly increased complexity, and thus potential
1      for error; for some code this can be just as transparent, but in
1      practice it can been very difficult to build multiple programs in
1      one directory and one program in multiple directories.  Code
1      written for this model tends to separate definitions of non-inline
1      member templates into a separate file, which should be compiled
1      separately.
1 
1  G++ implements the Borland model on targets where the linker supports
1 it, including ELF targets (such as GNU/Linux), Mac OS X and Microsoft
1 Windows.  Otherwise G++ implements neither automatic model.
1 
1  You have the following options for dealing with template
1 instantiations:
1 
1   1. Do nothing.  Code written for the Borland model works fine, but
1      each translation unit contains instances of each of the templates
1      it uses.  The duplicate instances will be discarded by the linker,
1      but in a large program, this can lead to an unacceptable amount of
1      code duplication in object files or shared libraries.
1 
1      Duplicate instances of a template can be avoided by defining an
1      explicit instantiation in one object file, and preventing the
1      compiler from doing implicit instantiations in any other object
1      files by using an explicit instantiation declaration, using the
1      'extern template' syntax:
1 
1           extern template int max (int, int);
1 
1      This syntax is defined in the C++ 2011 standard, but has been
1      supported by G++ and other compilers since well before 2011.
1 
1      Explicit instantiations can be used for the largest or most
1      frequently duplicated instances, without having to know exactly
1      which other instances are used in the rest of the program.  You can
1      scatter the explicit instantiations throughout your program,
1      perhaps putting them in the translation units where the instances
1      are used or the translation units that define the templates
1      themselves; you can put all of the explicit instantiations you need
1      into one big file; or you can create small files like
1 
1           #include "Foo.h"
1           #include "Foo.cc"
1 
1           template class Foo<int>;
1           template ostream& operator <<
1                           (ostream&, const Foo<int>&);
1 
1      for each of the instances you need, and create a template
1      instantiation library from those.
1 
1      This is the simplest option, but also offers flexibility and
1      fine-grained control when necessary.  It is also the most portable
1      alternative and programs using this approach will work with most
1      modern compilers.
1 
1   2. Compile your template-using code with '-frepo'.  The compiler
1      generates files with the extension '.rpo' listing all of the
1      template instantiations used in the corresponding object files that
1      could be instantiated there; the link wrapper, 'collect2', then
1      updates the '.rpo' files to tell the compiler where to place those
1      instantiations and rebuild any affected object files.  The
1      link-time overhead is negligible after the first pass, as the
1      compiler continues to place the instantiations in the same files.
1 
1      This can be a suitable option for application code written for the
1      Borland model, as it usually just works.  Code written for the
1      Cfront model needs to be modified so that the template definitions
1      are available at one or more points of instantiation; usually this
1      is as simple as adding '#include <tmethods.cc>' to the end of each
1      template header.
1 
1      For library code, if you want the library to provide all of the
1      template instantiations it needs, just try to link all of its
1      object files together; the link will fail, but cause the
1      instantiations to be generated as a side effect.  Be warned,
1      however, that this may cause conflicts if multiple libraries try to
1      provide the same instantiations.  For greater control, use explicit
1      instantiation as described in the next option.
1 
1   3. Compile your code with '-fno-implicit-templates' to disable the
1      implicit generation of template instances, and explicitly
1      instantiate all the ones you use.  This approach requires more
1      knowledge of exactly which instances you need than do the others,
1      but it's less mysterious and allows greater control if you want to
1      ensure that only the intended instances are used.
1 
1      If you are using Cfront-model code, you can probably get away with
1      not using '-fno-implicit-templates' when compiling files that don't
1      '#include' the member template definitions.
1 
1      If you use one big file to do the instantiations, you may want to
1      compile it without '-fno-implicit-templates' so you get all of the
1      instances required by your explicit instantiations (but not by any
1      other files) without having to specify them as well.
1 
1      In addition to forward declaration of explicit instantiations (with
1      'extern'), G++ has extended the template instantiation syntax to
1      support instantiation of the compiler support data for a template
1      class (i.e. the vtable) without instantiating any of its members
1      (with 'inline'), and instantiation of only the static data members
1      of a template class, without the support data or member functions
1      (with 'static'):
1 
1           inline template class Foo<int>;
1           static template class Foo<int>;
1