Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Templates im object-file

0 views
Skip to first unread message

Frank Busse

unread,
Jul 12, 1994, 1:49:00 PM7/12/94
to
Hi C++-Gurus!

Ich habe da ein kleines Problem (das aber Abbild eines weitaus groesseren ist)
mit der Uebersetzung von template-Strukturen: Die folgenden drei Mini-Dateien
enthalten...

// "temp.h" definition eines struct Temp<T>
template <class T> struct Temp {T MinusEins (T);};

// "temp.cc" definition einer member-function Temp<T>::MinusEins
#include "temp.h"
template <class T> T Temp<T> :: MinusEins (T Arg) {return (Arg - 1);}

// "test.cc" Programm, das ein Temp<int> braucht
#include <iostream.h>
#include "temp.cc" // ### so geht's !!! (1)
//#include "temp.h" // ### so geht's nicht ?!? (2)
int main (int NArg){
Temp<int> Schablone;
cout << "Was soll ich mit " << Schablone.MinusEins (NArg) << " Argumenten?";
return 0;
}

Wenn ich (unter OS/2 mit dem GCC) dieses Programm uebersetze mit...
> D:\CPP\TEST> gcc test.cc -Wall -o test.exe -lgpp -liostream
... bekomme ich (ohne Fehlermeldungen) genau das, was ich erwarte:
> D:\CPP\TEST> test a b c d
> Was soll ich mit 4 Argumenten?

Wenn ich aber nur "temp.h" einbinde (in "test.cc" 1 auskommentiere, 2
aktiviere), "temp.cc" separat kompiliere und die beiden Teile anschliessend
zusammenlinke...
> D:\CPP\TEST> gcc test.cc temp.cc -Wall -o test.exe -lgpp -liostream
... findet der Linker die Funktion aus 'temp.cc' nicht mehr:
> ./ccc00251: Undefined symbol Temp<int>::MinusEins referenced from text
>segment

Und wenn ich mir mal die "temp.o" 'rauspicke, dann scheint sie mir mit gerade
mal 101 bytes doch auch recht mickrig. - Habt Ihr so spontan 'ne Idee, wo mein
Fehler liegen koennte?

Gruss, Frank

P. S.: Bitte, keine Flames … la "das kannste aber einfacher programmieren". Es
handelt sich wie gesagt um ein /Modell/ um genau das Problem von Templates in
object-files einzukreisen!

B-U-S-S-E --- wie Oeffentlicher Personen-Nahverkehr!

Juergen Hermann

unread,
Jul 15, 1994, 3:08:42 AM7/15/94
to
In a message of Tu 12-Jul-94 19:49, Frank Busse % MAUS AC3 (2:2452/101.6)
wrote:

FBMA> Wenn ich aber nur "temp.h" einbinde (in "test.cc" 1
FBMA> auskommentiere, 2 aktiviere), "temp.cc" separat kompiliere und
FBMA> die beiden Teile anschliessend zusammenlinke...
FBMA> > D:\CPP\TEST> gcc test.cc temp.cc -Wall -o test.exe -lgpp
FBMA> -liostream
FBMA> ... findet der Linker die Funktion aus 'temp.cc' nicht mehr:

r.14.4: "A function template definition is needed to generate specific versions
of the template; ...". Es geht halt nicht anders!

Ciao, Juergen


Peter Jacobi

unread,
Jul 19, 1994, 8:36:00 AM7/19/94
to
JH> FBMA> Wenn ich aber nur "temp.h" einbinde (in "test.cc" 1
JH> FBMA> auskommentiere, 2 aktiviere), "temp.cc" separat kompiliere und
JH> FBMA> die beiden Teile anschliessend zusammenlinke...
JH> FBMA> > D:\CPP\TEST> gcc test.cc temp.cc -Wall -o test.exe -lgpp
JH> FBMA> -liostream
JH> FBMA> ... findet der Linker die Funktion aus 'temp.cc' nicht mehr:
JH>
JH> r.14.4: Ae function template definition is needed to generate specific
JH> versions
JH> of the template; ...". Es geht halt nicht anders!

C++ Implementationen mit einer, gegenueber dem klassischen Compile/Link
Zyklus, verbesserten Template Unterstuetzung sind moeglich und meines
Wissens auch schon gezeigt worden. Auch mit normalen Compiler und Linker
laesst sich etwas Aehnliches machen: Die nichtaufgeloesten Referenzen koennen
zu einer automatischen Erzeugung eines Quelltextes fuehren, der die
fehlenden Instantierungen des Templates enthaelt, und dann wird wieder
compiliert ung gelinkt.

Oder der Programierer fuegt im .cpp explitite Instantierungen fuer alle
Typen, die er braucht, ein.

Gruesse,
Peter

Elmar Sonnenschein

unread,
Jul 20, 1994, 4:07:00 AM7/20/94
to
Soweit alles richtig. Nur dass

FB>> struct TempInt : public Temp<int> {};

natuerlich noch nicht zur Erzeugung von 'TempInt' fuehrt, sondern nur die
entsprechende Deklaration darstellt. Erst mit der Definition (z.B.
'TempInt ti;') wuerde eine Instanz erzeugt. Diese nuetzt in einer Bibliothek
jedoch wenig.

Der einizge Weg, Template-Details in Bibliotheken zur verbergen (so es denn
unbedingt noetig ist), ist, die entsprechenden Elemente nicht als Templates zu
realisieren und dann von den eigentlichen Templates aufrufen zu lassen bzw.
diese von den nicht-Template-Klassen abzuleiten.

MfG, Elmar


Matthias Pruksch

unread,
Jul 20, 1994, 2:11:00 PM7/20/94
to
Hallo Frank,

FB> Erst wenn der Compiler weiss, wie gross ein Objekt wird, kann er einen
passenden
FB> Code erzeugen. Der Compiler weiss /nicht/, wie gross er ein 'template'
machen
FB> soll. - Also kann der Compiler keinen Code mit einem nicht-initialisierten
FB> 'template' erzeugen. Also ist es /prinzipiell/ unmoeglich, ein 'class
FB> Temp<template class>' beispielsweise aus einer Library zur Verfuegung zu
FB> stellen. - Richtig?

Ja, das kommt schon gut !!! Wichtig ist, dass der Compiler keine fertige
Funktion anfertigen kann, die dann der Linker der Library entnehmen koennte,
um dann ein Programm zu binden !!!

Wenn eine Funktion z.B. zwei Variablen vom Typ <class T> multiplizieren muss,
dann weiss der Compiler noch nicht welche Multiplikationsroutine er nehmen
soll, da das ja vom Typ abhaengt !!!

Also kann er keine fertige Funktion erstellen.

Der Linker aber, sucht alle Funktionen zusammen, die benoetigt werden, um ein
Programm zu erstellen.

Deshalb muss immer der Compiler die Definition des Templates kennen, wenn
eine entsprechende Operation benoetigt wird. Durch das includen oder direkte
Einbinden machst Du genau das !!!

Fuer den spezifischen Typ, der in temp.cc benutzt wird, wird dann auch eine
Funktion erstellt und der Linker ist zufrieden.

Wird kein Typ spezifiziert, dann nimmt der Compiler an, dass das nur
unnoetiger Balast ist und erstellt keine Funktion.

Dann meckert natuerlich der Linker!!!

Gruss Matthias Pruksch
>O<

Frank Busse

unread,
Jul 21, 1994, 3:55:00 AM7/21/94
to
Hi Elmar!

ES>Erst mit der Definition (z.B. 'TempInt ti;') wuerde eine Instanz
ES>erzeugt.

Arrggh!!! (So langsam sollte ich wohl meinen Footer fuer diese Gruppe auf
"Vorsicht, Anfaenger!" setzen)

ES>Diese nuetzt in einer Bibliothek jedoch wenig.

Klar. Deswegen hatte ich's bei der /Deklaration/ belassen :-/

ES>die entsprechenden Elemente nicht als Templates zu realisieren und dann
ES>von den eigentlichen Templates aufrufen zu lassen bzw. diese von den
ES>nicht-Template-Klassen abzuleiten.

Danke. So werde ich's wohl jetzt machen. - Schade eigentlich...

Gruss, Frank

0 new messages