🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: de.comp.lang.c++
Article #1728

most-faq: template instantiation&compiler specifics

#1728
From: root
Date: Sun, 03 Mar 1996 08:19
95 lines
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-intern

Show 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