Article View: de.comp.lang.c++
Article #1728most-faq: template instantiation&compiler specifics
From: root
Date: Sun, 03 Mar 1996 08:19
Date: Sun, 03 Mar 1996 08:19
95 lines
5333 bytes
5333 bytes
Wenn mich nicht alles taeuscht, ist die Frage nach dem richtigen Umgang mit
template-member-Funktionen (tmf) die am haeufigsten gestellte und nie richtig
beantwortete Frage.
Daher hier, nach Lektuere von
- g++-info:templates,
- SUN C++ 4.0.1 user manual,
- FAQ for g++ and libg++,
- threads in comp.lang.c++(.moderated), comp.std.c++, de.comp.lang.c++,
gnu.lang.help mit subject "... template ...",
meine Version der Frage.
Ursache des Problems ist wohl, dass manche c++-Fans (leider auch die meisten
Compilerhersteller) meinen, der Compiler muesste so schlau sein, nur die tmf
Instanzen zu erzeugen, die tatsaechlich verwendet werden. Dazu gibt es laut
g++-info (bestaetigt durch ein posting eines *borland.com und SUNs C++
4.0.1-Handbuch) zwei Ansaetze:
1. Borland-C++:
Template-Deklaration und -Definition in die header-Datei schreiben, ein
spezieller Linker filtert die entstandenen Redundanzen heraus.
Nachteil:
Damit kann man das Konzept:
- header-Datei = Schnittstellendeklaration,
- Programm-Datei = Programmimplementation,
endgueltig vergessen. Und damit auch die Wartung groesserer Projekte.
2. Cfront (AT&T, mit Einschraenkungen SUN C++):
Irgendwoher "weiss" der Compiler, wo die tmf definiert sind, bestimmt,
welche Instanzen notwendig sind und erzeugt diese.
Leider fehlt bei den meisten Rechnern die Einfuelloeffnung fuer Maggi.
SUN behilft sich mit TemplateDB-Verzeichnissen. Das scheint aber, wenn
ueberhaupt, nur zu funktionieren, wenn
- header und source den gleichen Basisnamen haben und
- alle Quellen im gleichen Verzeichnis stehen.
g++ bietet in der Standardversion eine aehnliche Moeglichkeit durch die
Verwendung von "#pragma interface <FILE>"/"#pragma implementation", mit
der Compiler-Optionen "-fexternal-templates" und dem Eintrag
"template class <Instanzen-Bezeichnung>;" in der tmf-Definitionsdatei.
Nachteil:
Es entsteht ein zusaetzlicher Verwaltungsaufwand, mit dem sich der
Programmentwickler sehr bald selbst beschaeftigen muss. Bei grossen
Projekten wird ein erheblicher Teil der Dateistruktur in die
Programmquellen einfliessen. Dann ist es mit der Modularitaet und
Wiederverwendbarkeit ebenfalls vorbei.
Gemeinsammer Nachteil der beiden Methoden:
sie sind miteinander unvertraeglich.
Ergebnis:
Der Ansatz "der Compiler/Linker erzeugt aus templates genau die benoetigten
Instanzen" ist ebenso schoen wie falsch:
Hoffen: ja, natuerlich; Wissen: nein, leider; Tun: _NEIN_! niemals!
Bleibt als 3. Moeglichkeit die triviale Loesung der "expliziten
Instanzenbildung"
Ansatz:
- Templates sind Werkzeuge, mit denen man durch einmaliges Codieren mehrere
aehnliche Klassen/Funktionen erzeugt.
- Aus einer Quelldatei erzeugte Objektdateien enthalten den Code, der
auf Grund des Inhaltes der Quelldatei, dort eingeschlossener header-
Dateien, sowie der Compiler-Optionen erzeugt wurde.
- Beim Uebersetzen der tmf muss der Compiler wissen, welche Instanzen
erzeugt werden sollen.
- Beim Uebersetzen der Anwendungsprogramme sollte der Compiler wissen,
welche Instanzen zur Verfuegung stehen, d.h. wann er eine Fehlermeldung
ausgeben muss.
Vorteil:
- Selbst MS-Programmierer muessten in der Lage sein, das zu implementieren.
- Waere dies die allgemein empfohlene, standardmaessig implementierte Art,
wuerde die Zahl der postings vom Typ "HELP: LINKER ERROR: UNDEFINED"
drastisch reduziert.
- Der Uebergang zwischen "eigenen" templates und templates fuer/in
libraries ist zwanglos moeglich.
- Die aus C uebernommenen Ansaetze, die Modularisierung in die
Dateistruktur abzubilden, bleiben erhalten.
Realisierung:
1. g++:
Mit Eintrag "template class <Instanzen-Bezeichnung>;" fuer jede gewuenschte
Instanz in der Datei mit den Definitionen der tmf erzwingt man die
Erzeugung der entsprechenden Memberfunktionen. Die Compiler-Option
"-fno-implicit-templates" sorgt dafuer, dass diese global verwendet werden.
Nachteil (soweit ich es bisher ausprobiert habe):
- Bei Verwendung von "-fno-implicit-templates" werden auch inline
template-Funktionen nicht mehr automatisch expandiert.
- Schade, aber nicht wirklich stoerend: "template class ..." muss in
der Quelle, nicht im header stehen (sonst gibt's "multiple
defined"). So merkt erst der Linker, wenn eine Instanz fehlt.
2. SUN C++ 4.0.1:
Mit dem Eintrag "template class ..." kann er nichts anfangen. Bisher weiss
ich nichts Besseres als in der Definitionsdatei der tmf dummy-Programme
anzuhaengen, die jede Memberfunktion einmal afurufen. Das kann ja wohl
nicht wahr sein!
Zusaetzlich scheint man dem Compiler die Option "-pto" geben zu muessen,
damit die tmf-Instanzen global werden. Fuer die Bildung der Modul-
libraries scheint man "CC -xar" (statt "ar") verwenden zu muessen.
MfG, Gerhard.
Technical Details
Message-ID:
<4hbknf$7nl@Dortmund.Germany.EU.net>Path:
arc1-ca.pugleaf.net!Dortmund.Germany.EU.net!news-internShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!Dortmund.Germany.EU.net!news-intern From: root@gt-priv.m.eunet.de (root) Newsgroups: de.comp.lang.c++ Subject: most-faq: template instantiation&compiler specifics Date: 3 Mar 1996 08:19:59 GMT Organization: Gerhard Traeger Distribution: world Message-ID: <4hbknf$7nl@Dortmund.Germany.EU.net> NNTP-Posting-Host: gt-priv.m.eunet.de X-Newsreader: suck 2.0