2017-02-03 5 views
1

Warum Vorlagenfunktionen nicht im LLVM-IR angezeigt werden, wenn die Funktion nicht aufgerufen wird, wenn LLVM IR von einem C++ Code ausgegeben wird, im Gegensatz zu anderen Arten von Funktionen (int, float ...), die in der llvm vorhanden sein werden ir Beispiel: die folgende Funktion func1 doesnt Show in llvm irWarum Vorlagenfunktionen im LLVM-IR nicht angezeigt werden?

template <class tmp> 
tmp func1() { 
    // ... 
} 

Aber diese Funktion func2 zeigt immer in llvm ir

int func2() { 
    // ... 
} 
+1

Dies ist keine * Template-Funktion *. Dies ist eine * Funktionsvorlage *. Es ist keine Funktion, sondern ein Entwurf einer zukünftigen Funktion. Es ist völlig gleichgültig.'func ' wäre eine * Template-Funktion *, d. h. eine * Funktionsvorlage * mit allen bereits bekannten Template-Parametern. Dies * instanziiert * die Vorlage, wodurch sie "materialisiert" wird. – AnT

Antwort

5

Dies ist sein Da Ihre Vorlagen keine Funktionen sind, handelt es sich um Funktionsvorlagen. Sie sind keine Ergebnisse, bis sie mit Argumenten instanziiert werden. Nehmen Sie zum Beispiel diesen Code:

template<typename T> 
T foo() { /* ... */ } 

Das wird noch keinen Code ausgeben.

Aber auf der anderen Seite:

template<typename T> 
T foo() { /* ... */ } 

int test() { 
    return foo<int>(); 
} 

Will Ausgang sowohl der Code für test und foo<int>.

können Sie instanziiert auch manuell eine Vorlage wie folgt aus:

template int foo<int>(); 
4

Das mit how C++ templates work zu tun hat. Da der Compiler nicht weiß, was tmp ist, bis Sie die Funktion aufrufen (oder genauer gesagt, wenn Sie es instanziieren), weiß es nicht, wie man Code dafür schreibt. Betrachten wir zum Beispiel diese Vorlage:

template <typename T> 
T add(T left, T right) { 
    return left + right; 
} 

Wenn T eine ganze Zahl ist, dann ist die Funktion Körper eine ganze Zahl zus. Wenn T ein Double ist, ist es eine Gleitkommazahl. Wenn T ein std::string ist, ist es ein Funktionsaufruf zu std::string::operator+.

Da es in einem C++ - Programm viele Typen gibt, von denen viele hinzugefügt werden können und so ziemlich jeder auf verschiedene Arten hinzugefügt wird, kann der Code für die Funktion erst erstellt werden, wenn dieser Typ bekannt ist. Wenn es versucht wird, es für alle möglichen Typen T zu tun, würden Sie eine kombinatorische Explosion von möglichen Implementierungen bekommen, von denen fast alle nie benutzt werden. Ihre Kompilierzeit und binäre Größe wäre riesig für wenig oder keinen Nutzen.


Dinge werden etwas komplizierter mit class templates. Eine Instantiierung einer Klassenvorlage muss nicht alle Funktionen instanziieren, wenn sie nicht aufgerufen werden. Möchten Sie zu unserem Beispiel zurück, wenn wir stattdessen schrieb:

template <typename T> 
class Adder { 
    T add(T left, T right) { 
     return left + right; 
    } 
}; 

Adder<int> a; 

diese noch würde Adder<int>::add noch nicht instanziiert obwohl der Compiler alle Informationen, muss wissen, dass add<int> potentiell interessant, weil man eigentlich nicht tun anrufen oder anderweitig instanziieren.

Verwandte Themen