2009-08-02 7 views
25

Ich möchte einige Template Code debuggen, um es besser zu verstehen.
Ich bin neu in Metaprogrammierung und es ist leider schwer für mich zu bekommenC++ Template Metaprogrammierung - Kann der generierte Code ausgegeben werden?

Wenn ich die Ausgabe versuchen, die vorverarbeitet Quelldateien Ich erhalte 125 000 Codezeilen:./

So gibt es eine Wie kann ich den generierten Code sehen? (Die Bibliothek, die ich verwende, ist SeqAn)

+2

Nein, aber es sollte. Jemand sollte dies als ein Clang-Projekt tun: D –

+0

Beachten Sie, dass aufgrund von [SFINAE] (https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error) der Code erhalten Sie einfach durch Ersetzen jeder Vorlage mit einer fest codierten Alternative wäre wahrscheinlich illegal. Z.B. Solange es nie aufgerufen wird, kann eine Methode einer Template-Klasse Dinge aufrufen, die nicht existieren. – MvG

+1

@JosephGarvin Es gibt jetzt ein Clang-basiertes Projekt (s). Die neueste aktive Version von [Templight, der Clomb-basierte Vorlage Instanziierung Profiler und Debugger] (https://github.com/mikael-s-Persson/Templight), [Templar Visualizer] (https://github.com/ Schulmar/Templer), sowie [Metashell] (https://github.com/sabel83/metashell). –

Antwort

21

Nein ist es nicht. Der Präprozessor hat nichts mit der Template-Verarbeitung zu tun, die vom Compiler ausgeführt wird. Vorlagen erzeugen keinen C++ - Code, genauso wenig wie ein Funktionsaufruf - sie sind ein integraler Bestandteil der C++ - Sprache selbst.

+0

Während dies allgemein gilt, gilt dies theoretisch auch für den Präprozessor. In der Praxis besteht die einfachste Implementierung darin, C++ - ähnlichen Code als Ausgabe der Präprozessorstufe zu erzeugen, jedoch nicht für Template-Instanziierungen. Das Gegenteil wäre unvernünftig, aber technisch nicht unmöglich. Das Hauptproblem besteht in der Suche nach Namen, und der Compiler könnte bei der Instanziierung von Templates eindeutige Namen generieren. – MSalters

+0

Um ehrlich zu sein, können Sie den Debugger immer noch verwenden, um den berechneten Typ anzuzeigen, wenn Sie ihn instanziieren. Ich habe ein Beispiel für die Verwendung von Visual C++ gemacht. Ich habe es sehr oft für meine Meta-Programme benutzt. – ovanes

5

Dies ist möglicherweise die Antwort auf Ihre Frage:

C++ Template preprocessor tool

scheint die letzte Person, die erfüllt die gefragt - obwohl ich nicht, warum sich vorstellen kann! Die Ausgabe eines C++ - Compilers in C ist in der Regel ziemlich unlesbar, weil sie nicht als Verständigungshilfe dienen soll, sondern lediglich als eine Art tragbarer Assemblersprache.

1

Im Allgemeinen ist es nicht möglich, den gesamten Code auszugeben. Aber was ich sehr interessant fand, ist die Fähigkeit, Visual C++ - Debugger zu verwenden, um Ihnen den Typ zu zeigen. Nimm das einfache Metaprogramm:

template<class Head, class Tail> 
struct type_list 
{ 
    typedef Head head; 
    typedef Tail tail; 
}; 

struct null_type 
{}; 

template<class List> 
struct list_head 
{ 
    typedef typename List::head head; 
}; 

template<class List> 
struct list_tail 
{ 
    typedef typename List::tail tail; 
}; 

template<class List> 
struct list_length 
{ 
    static const size_t length = 1+list_length< typename list_tail<List>::tail >::length; 
}; 

template<> 
struct list_length<null_type> 
{ 
    static const size_t length = 0; 
}; 


int main() 
{ 
    typedef 
    type_list 
    < int 
    , type_list 
     < double 
     , type_list 
     < char 
     , null_type 
     > 
     > 
    >  my_types; 

    my_types test1; 

    size_t length=list_length<my_types>::length; 

    list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2; 

} 

Ich habe gerade meine Meta-Typen instanziiert. Dies sind immer noch leere C++ - Klasseninstanzen, die mindestens 1 Byte lang sind. Jetzt kann ich einen Haltepunkt nach der letzten Instanziierung test2 setzen und sehen, welche Typen/Werte Länge, test1 und test2 ist:

Hier ist, was der Debugger zeigt:

length 3 unsigned int 
test1 {...} type_list<int,type_list<double,type_list<char,null_type> > > 
test2 -52 'Ì' char 

Jetzt Sie wissen, die head hat dir ein Zeichen zurückgegeben, deine Liste enthält int, double, char und wird mit null_type beendet.

Das hat mir sehr geholfen. Manchmal müssen Sie den wirklich unordentlichen Typ in einen Texteditor kopieren und ihn in eine lesbare Form formatieren, aber das gibt Ihnen die Möglichkeit zu verfolgen, was drin ist und wie es berechnet wird.

Hoffnung, die hilft,
Ovanes

22

Nein, im Allgemeinen, es kann nicht getan werden. Vorlagen sind einfach Teil der C++ - Sprache, sie sind kein separater Präprozessor, daher generieren sie keinen C++ - Code.

Die übliche Lösung besteht darin, Ihren Code mit statischen Einträgen und anderen Tests zu bestreuen, um sicherzustellen, dass die richtigen Vorlagen auf die richtige Weise instanziiert werden.

Sobald Sie in Ihrem metaprogramming verloren anfangen, diese einfachen Trick können Sie festlegen, welche Art ein Template-Parameter wirklich helfen, festzustellen ist:

// given a variable t of an unknown type T 
int*** i = t; 

Wenn der Compiler dies trifft, es wird ein auszudrucken schön und einfach Fehlermeldung "Konnte nicht <long, detailed typename> in int *** konvertieren", so dass Sie leicht überprüfen können, dass der Vorlagenparameter T tatsächlich der Typ ist, von dem Sie denken, dass er es sein sollte.

14

prüfen my publication on C++ template metaprogram debugging

Von Seite 6 Sie sehen, wie es funktioniert. Für bestimmte Zwecke brauchen Sie nicht die gesamte Toolchain, es kann von Hand gemacht werden.

Ich habe ein Visual C++ - Add-In zusammengestellt, in dem Sie Haltepunkte usw. platzieren können, aber es war eher ein Beweis des Konzepts als ein Werkzeug für den täglichen Gebrauch.

Wir haben an einem grafischen Frontend gearbeitet, das alle Instanziierungen zeigt, Debugging erlaubt, Profiling. Leider können wir für dieses Tool kein Veröffentlichungsdatum versprechen, da wir es in unserer relativ begrenzten Freizeit tun.

UPDATE: der Debugger und Profiler ist verfügbar here

UPDATE: C++Now presentation

+0

Sieht interessant aus! –

Verwandte Themen