2010-12-15 9 views
31

ist es eine Möglichkeit, den Compiler instanziiert-Code für eine Template-Funktion oder eine Klasse in C zu wissen ++Können wir sehen den Vorlagencode instanziiert von C++ Compiler

Angenommen, ich habe das folgende Stück Code

template < class T> T add(T a, T b){ 
      return a+b; 
} 

jetzt, wenn ich rufe

add<int>(10,2); 

ich möchte die Funktion kennen, die Compiler für int bestimmte Version erstellt.

Ich verwende G ++, VC++. Es wird hilfreich sein, wenn einige mir helfen können, die Compiler-Optionen aufzuzeigen, um dies zu erreichen.

Hoffe die Frage ist klar. Danke im Voraus.

+2

Möchten Sie die Funktion in C++ oder in Assembly sehen? Wenn Sie in Assembly sind, verwenden Sie 'g ++ -S'. – Job

+2

Eine eng verwandte Frage: http://stackoverflow.com/q/4332286/57428 – sharptooth

Antwort

17

Sie können auf jeden Fall die Assembler-Code sehen von der g erzeugt ++ unter Verwendung der „-S“ Option.

Ich glaube nicht, dass es möglich ist, den "C++" entsprechenden Template-Code anzuzeigen - aber ich würde immer noch wollen, dass ein g ++ - Entwickler, warum - ich kenne nicht die Architektur von gcc.

Wenn die Montage verwenden, können Sie den resultierenden Code suchen überprüfen, was Ihre Funktion ähnelt. Als Ergebnis der laufenden gcc -S -O1 {yourcode.cpp}, habe ich diese (AMD64, gcc 4.4.4)

_Z3addIiET_S0_S0_: 
.LFB2: 
    .cfi_startproc 
    .cfi_personality 0x3,__gxx_personality_v0 
    leal (%rsi,%rdi), %eax 
    ret 
    .cfi_endproc 

Welche wirklich nur ein int Zusatz (Leal) ist.

Jetzt, wie man den C++ Namen Mangler entschlüsselt? es ist ein Dienstprogramm, C++ filt genannt, fügen Sie die kanonische (C-Äquivalent) Name und Sie die demangled c bekommen ++ Äquivalent

[email protected] /dev/shm $ c++filt 
_Z3addIiET_S0_S0_ 
int add<int>(int, int) 
+0

Wenn Leute den generierten Vorlagencode sehen konnten, wäre es wahrscheinlich zu viel zu lesen sowieso ... im Falle der STL –

+3

Nun Leute dürfen die generierte Assembly sehen, es ist schon ziemlich weit, aber manchmal ist es genau das, was Sie brauchen, um wertvolle Einblicke zu gewinnen. – qdot

+1

@qdot es ist völlig anders, die Assembly und den C++ generierten Code zu sehen. Manchmal möchten Sie die Hierarchie der Klassen mithilfe der TypeLists generieren, dann müssen Sie die Ergebnisse wahrscheinlich als C++ - Code sehen, um in Ihrer Hierarchie sicher zu sein. Die Montage hilft in diesem Fall überhaupt nicht. – AlexTheo

3

Am einfachsten ist es, die generierte Baugruppe zu überprüfen. Sie können eine Assembly-Quelle abrufen, indem Sie das -S Flag für g ++ verwenden.

2

Wenn der Optimierer seine Taten getan hat, haben Sie wahrscheinlich nichts mehr übrig, der wie ein Funktionsaufruf aussieht. In Ihrem konkreten Beispiel werden Sie definitiv mit einer Inline-Ergänzung enden, schlimmer noch. Abgesehen davon können Sie den generierten Assembler während der Kompilierung immer in einer separaten Datei ausgeben, und dort liegt Ihre Antwort.

24

Wenn Sie die Montage Ausgabe sehen wollen, verwenden Sie diese:

g++ -S file.cpp 

Wenn Sie einige (pseudo) C++ Code sehen möchten, die GCC generiert, können Sie diese verwenden:

g++ -fdump-tree-original file.cpp 

Für Ihre add Funktion, erhalten Sie folgende Ausgabe etwas wie

;; Function T add(const T&, const T&) [with T = int] (null) 
;; enabled by -tree-original 

return <retval> = (int) *l + (int) *r; 

(I geleitet, um die Parameter durch Verweis die Ausgabe ein wenig interessanter zu machen)

1

Wenn Ihr auf der Suche nach dem äquivalenten C++ Code dann nicht. Der Compiler generiert es nie. Es ist viel schneller für den Compiler, seine Zwischenrepräsentation direkt zu erzeugen, als erst C++ zu generieren.

8

Clang (https://clang.llvm.org/) kann ziemlich Druck AST von instanziiert Vorlage:

Für Ihr Beispiel:

test.cpp

template < class T> T add(T a, T b){ 
    return a+b; 
} 

void tmp() { 
    add<int>(10,2); 
} 

Befehl zum Pretty-Print AST:

$ clang++ -Xclang -ast-print -fsyntax-only test.cpp 

C Lang-5.0-Ausgabe:

template <class T> T add(T a, T b) { 
    return a + b; 
} 
template<> int add<int>(int a, int b) { 
    return a + b; 
} 
void tmp() { 
    add<int>(10, 2); 
} 
Verwandte Themen