Your Browser is not longer supported

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

{{viewport.spaceProperty.prod}}

Generieren von expliziten Template-Instanziierungsanweisungen (ETR-Dateien)

&pagelevel(4)&pagelevel

In manchen Fällen, z.B. wenn die automatische Instanziierung nicht sinnvoll einsetzbar ist, bietet sich für den Programmierer die Möglichkeit, die explizite (manuelle) Instanziierung zu verwenden, um die Sourcen entsprechend zu erweitern.
Um diesen Vorgang zu erleichtern, kann eine ETR-Datei (ETR - Explicit Template Request) erstellt werden, die die Instanziierungs-Anweisungen für die verwendeten Templates enthält, die in eine Source übernommen werden können.
Die Optionen zur Erstellung dieser ETR-Datei sind im Abschnitt „Template-Optionen“ dargestellt.
Die Option beinhaltet drei Fälle: -T etr_file_none (default) /_all /_assigned. Bei der Angabe _none wird die Datei nicht generiert, bei _all werden alle relevanten Informationen ausgegeben, bei _assigned nur die angegebenen Informationen.

Die Templates, die bei der ETR-Analyse berücksichtigt werden, können in folgende Klassen eingeteilt werden:

  • Templates, die in der Übersetzungseinheit explizit instanziiert wurden. Diese werden bei _all ausgegeben.

  • Templates, die vom Prälinker der Übersetzungseinheit zugeordnet und dann darin instanziiert wurden. Die Ausgabe ist sowohl mit _all als auch mit _assigned möglich.

  • Templates, die in der Übersetzungseinheit verwendet wurden und die hier auch instanziiert werden können. Sie werden mit _all ausgegeben.

  • Templates, die in der Übersetzungseinheit verwendet wurden, hier aber nicht instanziiert werden können. Auch diese werden bei _all ausgegeben.

Der Inhalt einer ETR-Datei hat folgende Form:

  • In einer Kopfzeile wird durch Kommentare darauf hingewiesen, dass es sich um eine generierte Datei handelt.

  • Für jedes Template werden drei logische Zeilen erzeugt (vgl. Beispiel):

    • eine Kommentarzeile mit dem Text ’The following template was’

    • eine Kommentarzeile, die die Art der Instanz angibt (z.B ’explicitly instantiated’) 

    • eine Zeile, die die explizite Instanziierung für diese Instanz beschreibt. Diese enthält den externen Namen der Instanz. Dieser Name entspricht dem Eintrag in der ii-Datei und kann auch dem Binder-Listing bzw. der Binder-Fehlerliste entnommen werden

Hinweise

  • Sind die oben angegebenen Zeilen zu lang, so werden sie mit dem in C++ üblichen „Backslash newline“ umbrochen.

  • Die Reihenfolge der ausgegebenen Templates ist nicht definiert. Nach einer Recompilierung oder einer Änderung der Source kann die Reihenfolge anders sein.

  • Die logische Zeile drei ist besonders interessant für die Übernahme in eine Source.

  • Kommentare sind grundsätzlich in Englisch.

Für die Nutzung der ETR-Datei erscheinen folgende zwei Szenarien sinnvoll:

  1. Der Compiler wird während der Entwicklung mit der Option -T auto und -T etr_file_assigned aufgerufen.
    Die in den ETR-Dateien ausgegebenen Instanziierungs-Anweisungen werden in die zugehörigen Sourcen mit aufgenommen. Der Produktivbetrieb wird dann mit der Option -T none oder -T auto beim nächsten Compile-Aufruf vorgenommen.
    Der Vorteil dieser Variante liegt in der deutlich reduzierten Zeit für das Prälinken im Produktivbetrieb.

  2. Der Compiler wird während der Entwicklung mit der Option -T none und der Option - T etr_file_all aufgerufen.
    Nach dem Binden prüft der Entwickler jeden ungelösten Externverweis, ob dies ein Template ist und wenn ja, wo es instanziiert werden kann. Hilfreich dabei sind die ausgegebenen externen Namen. Anschließend wählt der Entwickler eine Source für die Instanziierung aus und nimmt die Instanziierungs-Anweisungen dort auf. Außerdem müssen noch die richtigen Header-Files inkludiert werden.
    In dieser Variante ist viel manuelle Arbeit erforderlich. Der Aufruf des Prälinkers kann allerdings dabei entfallen (-T none).
    Dieses Vorgehen erlaubt eine genaue Kontrolle über die Platzierung der Instanzen (wichtig z.B. bei Komponenten mit hohen Performance-Ansprüchen).

Beispiel 1

Für eine ETR-Datei, die beim Übersetzen (für die Nutzung etr_file_all) zweier Dateien x.c und y.c entsteht:

Beim Übersetzen wurde dieses Kommando verwendet:

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&_

Der Benutzer kann nun entscheiden, in welche Source er explizite Instanziierungen vornimmt (diese Entscheidung muss immer getroffen werden für Einträge mit „used in this module and can be instantiated here“), siehe Beispiel 2.
Danach muss nicht mehr mit der automatischen Template-Instanziierung weitergearbeitet werden.

Beispiel 2

Beispiel für die Nutzung von etr_file_assigned.
Gegeben seien zwei Dateien x.c und 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):
}

Diese Programme werden mit folgenden Kommandos erstmal übersetzt und das Prälinken durchgeführt:

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

Danach existiert eine Datei x.o.etr (da nur x Template-Instanziierungen zugeordnet werden), die wie folgt aussieht

// 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&_

Die wichtigen Zeilen werden dann in die Datei x.c aufgenommen, wodurch folgende Datei x1.c entsteht:

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&_

Im Anschluss kann die Produktion mit folgenden Kommandos durchgeführt werden:

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

Beispiel 3

Folgendes Beispiel zeigt die vier Klassen von Templates, die ausgegeben werden können. Die Annahmen sind wie im Beispiel 1.

Es werden folgende Kommandos eingegeben:

CC -c -T auto y.c
CC -y -T auto y.o (dadurch wird f(int) y.o zugewiesen)
CC -c -T auto -T etr_file_all x.c
CC -y -T auto -T etr_file_all x.o y.o

Danach entsteht folgende ETR-Datei 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&_