Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Libraries and templates

&pagelevel(4)&pagelevel

Instantiations for template entities (template functions, member functions and static data members of template classes) can be generated in automatic instantiation mode only if the object meets the following conditions:

  • It is not part of a .a library,

  • it contains a reference to the template entity or the can_instantiate pragma for that template entity,

  • and it contains all definitions needed for the instantiation.

A library that requires instances for its implementation must either contain these instances or provide special headers with can_instantiate pragmas. These two options are explained individually below.

  1. The library contains all required instances

    The main point to be observed here is to ensure that no duplicates are created when using multiple libraries.

    The instantiation of template entities in libraries can be achieved by the following methods:

    1. automatic instantiation of the template unit using the prelinker with the option -y (see "Options for selecting compilation phases").

      Caution

      If multiple libraries that require the same entity are used, there is a potential risk of duplicates being created, since a separate object is not created per entity. This can be avoided by using the -T add_prelink_files option (see "Template options").

    2. by explicitly instantiating all template entities with the instantiation directive template declaration or the instantiate pragma.

      The main point to be observed here is to ensure that a separate object is created per entity.

      Example

      Given:

      • a library l.a with references to the instances t_list(Foo1) and
        t_list(Foo2),

      • a header file listFoo.h with the declarations of t_list, Foo1 and Foo2

      • and a source file listFoo.C with the definitions of t_list, Foo1 and Foo2

      // l.h
      #ifndef L_H
      #define L_H
      #include "listFoo.h"
      void g();
      #endif
      
      // l.C (l.o is an element of l.a)
      #include "l.h"
      void g()   { 
         Foo1 f1;
         Foo2 f2;
         //... 
         t_list(f1);
         t_list(f2);
         //... 
         }
      
      //listFoo.h
      #ifndef LIST_FOO_H
      #define LIST_FOO_H
      template <class T> void t_list (T t);
      class Foo1 {...}; 
      class Foo2 {...};
      #endif
      
      //listFoo.C
      template <class T> class t_list (T t)
      {
         ...
      };
      

      Each of the referenced instances are contained in separate objects in the library l.a.

      // lf1.C (lf1.o is an element of l.a)
      // and contains an explicit instantiation for t_list(Foo1)
      #include "listFoo.h"
      template void t_list(Foo1);
      
      // lf2.C (lf2.o is element of l.a)
      // and contains an explicit instantiation for t_list(Foo2)
      #include "listFoo.h"
      #pragma instantiate void t_list(Foo2)
  2. The header files contain can_instantiate pragmas for all required instances.

    Example

    Given:

    • a library l.a with a reference to the instance t_list(Foo),

    • a header file listFoo.h with the declarations of t_list and Foo

    • and a source file listFoo.C with the definitions of t_list and Foo.

    // l.h
    #ifndef L_H
    #define L_H
    #include "listFoo.h"
    void g();
    #endif
    
    // l.C (l.o is an element of l.a)
    #include "l.h"
    void g()
    {
       Foo f;
       //...
       t_list(f);
       //...
    }
    
    //listFoo.h
    #ifndef LIST_FOO_H
    #define LIST_FOO_H
    template <class T> void t_list (T t);
    class Foo {...};
    #pragma can_instantiate t_list(Foo)
    #endif
    
    //listFoo.C
    template <class T> void t_list (T t) {...};
    

    The object user.o and the library l.a are linked together (CC user.o l.a).

    // user.C
    #include "l.h"
    int f ()
    {
       g();
    }
    

    user.C includes l.h, which in turn includes listFoo.h. Consequently, user.C contains notification that list(Foo) can be instantiated.

    Automatic instantiation by the prelinker produces only one instance t_list(Foo).

    Note

    In order to generate the needed instances, the can_instantiate pragma must be contained in a header file of the library that will be included by the user programs.