Your Browser is not longer supported

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

{{viewport.spaceProperty.prod}}

Generating explicit template instantiation statements (ETR files)

&pagelevel(4)&pagelevel

In some cases, for example, when automatic instantiation cannot be used effectively, the programmer has the option of using explicit (manual) instantiation in order to extend the sources as required.
To make this process easier, it is possible to create an ETR file (ETR - Explicit Template Request) which contains the instantiation statements for the templates used and which can be incorporated into a source.
The options for creating this ETR file are described in section “Template options”.

The option has three possibilities: -T etr_file_none (default) /_all /_assigned.If _none is specified, the file will not be generated, if _all is specified, all relevant information is output, if _assigned is specified, then only the specified information is output.

The templates taken into account during the ETR analysis can be divided into the following classes:

  • Templates that are instantiated explicitly in the compilation unit. These are output using _all.

  • Templates that are assigned by the prelinker to the compilation unit and then instantiated within the compilation unit. These can be output using both _all and _assigned.

  • Templates that are used in the compilation unit and that can be instantiated here. These are output using _all.

  • Templates that are used in the compilation unit, but cannot be instantiated here. These are output using _all.

The contents of an ETR file have the following format:

  • Comments in the header will indicate that the file is a generated file.

  • Three logical lines are created for each template (see the example below):

    • a comment line containing the text ’The following template was’

    • a comment line containing the type of the instance (for example, ’explicitly instantiated’)

    • a line which describes the explicit instantiation for this instance. This line contains the external name of the instance. This name is the same as the entry in the ii file and can also be obtained from the binder listing or the binder error listing

Notes

  • If the lines described above are too long, they will be wrapped in the usual C++ fashion using “Backslash newline”.

  • The sequence of the output templates is not defined. If recompilation takes place or a source is modified, the sequence may change.

  • The third logical line is particularly interesting when copying to a source.

  • The comments are always in English.

The following scenarios describe two possible uses of an ETR file:

  1. The compiler is called during development using the -T auto and -T etr_file_assigned options.
    The instantiation statements output to the ETR files are incorporated into the appropriate sources. Productive operation is then activated using the -T none or -T auto option the next time the compiler is called.
    The advantage of this method is the considerable reduction in the time it takes to complete prelinking during productive operation.

  2. The compiler is called during development using the -T none and -T etr_file_all options.
    After binding the developer checks each unresolved external reference to see whether it is a template, and if it is a template, when it can be instantiated. Particularly helpful in this case are the output external names. Then, the developer selects a source for the instantiation and inserts the instantiation statements there. In addition, the correct header files must also be included.
    This method requires a considerable amount of manual work. But you do not subsequently need to call the prelinker (-T none).
    This procedure offers you precise control over the placing of instances (which is important when using components with high performance requirements).

Example 1

For a single ETR file compiled using two files, x.c and y.c (when using etr_file_all).

The following command is used for compilation:

CC -c -T etr_file_all x.c y.c

Source x.c

template <class T> void f(T) {}
template <class T> void g(T);
template void f(long);
void foo()
{
         f(5);
         f(’a’);
         g(5);
}

Source y.c

template <class T> void f(T) {}
void bar()
{
         f(5);
}

ETR-file x.o.etr

// This file is generated and will be changed when the module is compiled

// The following template was
// explicitly instantiated
#pragma instantiate_mangled_id __1f__tm__2_l__FZ1Z_v&_

// The following template was
// used in this module and can be instantiated here
#pragma instantiate_mangled_id __1f__tm__2_i__FZ1Z_v&_

// The following template was
// used in this module and can be instantiated here
#pragma instantiate_mangled_id __1f__tm__2_c__FZ1Z_v&_

// The following template was
// used in this module
#pragma instantiate_mangled_id __1g__tm__2_i__FZ1Z_v&_

ETR-file y.o.etr

// This file is generated and will be changed when the module is compiled

// The following template was
// used in this module and can be instantiated here
#pragma instantiate_mangled_id __1f__tm__2_i__FZ1Z_v&_

The user can now decide in which source they wish to make explicit instantiations (this decision must always be made for entries with “used in this module and can be instantiated here”), see Example 2.
Then you will subsequently not need to use automatic template instantiation.

Example 2

Example of the use of etr_file_assigned.
Two files are specified x.c and y.c:

Source x.c

template <class T> void f(T) {}
template <class T> void g(T);
template void f(long);
void foo()
{
         f(5);
         f(’a’);
         g(5);
}

Source y.c

template <class T> void f(T) {}
void bar()
{
         f(5):
}

These programs are first compiled using the following commands and then prelinked:


CC -c -T auto -T etr_file_assigned x.c
CC -c -T auto -T etr_file_assigned y.c
CC -y -T auto -T etr_file_assigned x.o y.o


Then a file is created x.o.etr (since only x template instantiations are assigned) which looks like this:

// This file is generated and will be changed when the module is compiled

// The following template was
// instantiated automatically by the compiler
#pragma instantiate_mangled_id __1f__tm__2_i__FZ1Z_v&_

// The following template was
// instantiated automatically by the compiler
#pragma instantiate_mangled_id __1f__tm__2_c__FZ1Z_v&_

The important lines are inserted in the file x.c, thus creating the file x1.c:

template <class T> void f(T) {}
template <class T> void g(T);
template void f(long);
void foo()
{
         f(5);
         f(’a’);
         g(5);
}
#pragma instantiate_mangled_id __1f__tm__2_i__FZ1Z_v&_
#pragma instantiate_mangled_id __1f__tm__2_c__FZ1Z_v&_

Then production can be carried out using the following commands:

CC -c -T none x1.c
CC -c -T none y.c

Example 3

The following example shows the four classes of template that can be output. The assumptions are as in Example 1

The following commands are entered:


CC -c -T auto y.c
CC -y -T auto y.o (this assigns y.o to f(int))
CC -c -T auto -T etr_file_all x.c
CC -y -T auto -T etr_file_all x.o y.o


This creates the following ETR file, x.o.etr:

// This file is generated and will be changed when the module is compiled

// The following template was
// explicitly instantiated
#pragma instantiate_mangled_id __1f__tm__2_l__FZ1Z_v&_

// The following template was
// used in this module and can be instantiated here
#pragma instantiate_mangled_id __1f__tm__2_i__FZ1Z_v&_

// The following template was
// instantiated automatically by the compiler
#pragma instantiate_mangled_id __1f__tm__2_c__FZ1Z_v&_

// The following template was
// used in this module
#pragma instantiate_mangled_id __1g__tm__2_i__FZ1Z_v&_);