Frage

Angenommen, eine Header-Datei eine Funktion Vorlage definiert. Nehmen wir nun an zwei Implementierungsdateien diesen Header #include, und jeder von ihnen hat einen Aufruf an die Funktion Vorlage. In beiden Implementierungsdateien wird die Funktion Vorlage mit dem gleichen Typ instanziiert.

// header.hh
template <typename T>
void f(const T& o)
{
    // ...
}

// impl1.cc
#include "header.hh"

void fimpl1()
{
    f(42);
}

// impl2.cc
#include "header.hh"

void fimpl2()
{
    f(24);
}

kann man erwarten, dass der Linker würde über mehrere Definitionen von f() beschweren. Insbesondere dann, wenn f() keine Vorlage wäre dann in der Tat, dass der Fall wäre.

  • Wie kommt es, den Linker beschwert sich nicht über mehrere Definitionen von f()?
  • Ist es in der Norm festgelegt, dass der Linker diese Situation anmutig behandeln müssen? Mit anderen Worten, kann ich auf Programme ähnlich wie oben zählen immer zu kompilieren und verknüpfen?
  • Wenn der Linker klug genug sein kann, eine Reihe von Funktionsvorlage instantiations eindeutig zu machen, warum kann es das gleiche für reguläre Funktionen nicht tun, da sie identisch sind, wie der Fall für instanzierte Funktionsschablonen ist?
War es hilfreich?

Lösung

Um C ++ zu unterstützen, der Linker intelligent genug, um zu erkennen, dass sie alle die gleiche Funktion und wirft alle bis auf einen.

EDIT: Klarstellung: Der Linker nicht Funktion Inhalte vergleichen und festzustellen, dass sie gleich sind. Templated Funktionen sind als solche gekennzeichnet und der Linker erkennt an, dass sie die gleichen Signaturen haben.

Andere Tipps

Die Gnu C ++ Compiler Anleitung hat eine gute Diskussion dieser . Ein Auszug:

  

C ++ Templates sind die erste Sprache   Funktion mehr Intelligenz erfordern   aus der Umgebung als man in der Regel   findet auf einem UNIX-System. irgendwie ist der   Compiler und Linker müssen sicherstellen,   dass jede Vorlageninstanz auftritt   genau einmal, wenn es in der ausführbaren Datei   erforderlich ist, und gar nicht anders.   Es gibt zwei grundlegende Ansätze für diese   Problem, das als das bezeichnet werden   Borland-Modell und das Cfront Modell.

     

Borland Modell

     

Borland C ++ löste das Template   Instanziierung Problem durch die Zugabe von   Code-Äquivalent von gemeinsamen Blöcken   ihre Linker; der Compiler aussendet   Vorlageninstanzen in jeder Übersetzung   Einheit, die sie, und der Linker verwendet   kollabiert sie zusammen. Der Vorteil   nur dieses Modells ist, dass der Linker   muss die Objektdateien betrachten   sich; gibt es keine externe   Komplexität zu befürchten. Diese   Nachteil ist, dass die Kompilierung   wird, weil der Template-Code erhöht   kompiliert wiederholt wird. Code   geschrieben für dieses Modell dazu neigt,   umfassen Definitionen aller Vorlagen   in der Header-Datei muss, da sie sein   gesehen instanziiert werden.

     

Cfront Modell

     

Die AT & T C ++ Übersetzer, Cfront,   löste die Template-Instantiierung   Problem durch die Vorstellung von einer Schaffung   Template-Repository, ein automatisch   gepflegt Ort, an dem Template   Instanzen gespeichert. Eine modernere   Version des Repository arbeitet als   folgt: Da die einzelnen Objektdateien   gebaut werden, legt der Compiler jede   Template-Definitionen und   instantiations begegnet in der   Repository. Bei Link Zeitpunkt der Link   Wrapper fügt in den Objekten in der   Repository und stellt alle benötigten   Instanzen, die nicht zuvor waren   ausgesendet. Die Vorteile dieses Modells   sind optimale Übersetzungsgeschwindigkeit und   die Fähigkeit, das System Linker zu verwenden;   Borland Modell einer implementieren   Compiler-Anbieter muss auch ersetzen   der Linker. Die Nachteile sind,   in beträchtlichem Ausmaß der Komplexität erhöht und damit   Fehlerpotenzial; für einige Code   dies kann genauso transparent sein, aber   In der Praxis kann es sehr schwierig sein,   mehrere Programme in einem bauen   Verzeichnis und ein Programm in mehreren   Verzeichnisse. Code für diese geschrieben   Modell neigt dazu, getrennte Definitionen   nicht-inline Element Vorlagen in eine   separate Datei, die sein sollte   separat zusammengestellt.

     

Wenn Sie mit GNU ld Version 2.8 oder verwendet   später auf einem System, wie ELF   GNU / Linux oder Solaris 2, oder auf   Microsoft Windows, G ++ unterstützt die   Borland-Modell. Auf anderen Systemen G ++   weder automatisches Modell implementiert.

Dies ist mehr oder weniger ein Sonderfall nur für Vorlagen.

Der Compiler erzeugt nur die Vorlage instantiations, die tatsächlich verwendet werden. Da es keine Kontrolle darüber, welcher Code hat, wird von anderen Quelldateien erzeugt wird, hat es den Template-Code zu erzeugen, einmal für jede Datei, um sicherzustellen, dass das Verfahren überhaupt erzeugt wird.

Da es schwierig ist, diese zu lösen (der Standard hat eine extern Schlüsselwort für Vorlagen, aber g ++ nicht implementiert es nicht) der Linker einfach akzeptiert die mehrere Definitionen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top