10

Gegeben ein Template-Metaprogramm (TMP), erstellen C++ - Compiler Build-Statistiken, die die Anzahl der instanziierten Klassen zählen? Oder gibt es eine andere Möglichkeit, diese Nummer automatisch zu erhalten? So für z.B. die obiquitous faktoriellesAutomatisch die Anzahl der instanziierten Klassen in einem TMP zählen?

#include <iostream> 

template<int N> struct fact { enum { value = N * fact<N-1>::value }; }; 
template<> struct fact<1> { enum { value = 1 }; }; 

int main() 
{ 
    const int x = fact<3>::value; 
    std::cout << x << "\n"; 
    return 0; 
} 

Ich möchte die Nummer 3 (seit Tatsache < 3>, Tatsache < 2>, und Tatsache < 1> instanziiert) kommen. Dieses Beispiel ist natürlich trivial, aber wann immer Sie anfangen, z.B. Boost.MPL, Kompilierzeiten explodieren wirklich, und ich würde gerne wissen, wie viel davon wegen versteckter Klasseninstanziierungen ist. Meine Frage ist in erster Linie für Visual C++, aber Antworten für gcc würde auch geschätzt werden.

EDIT: kompiliert mein aktueller sehr spröde Ansatz für Visual C++ ist das Hinzufügen des Kompilierung Wechsels von einem von Stephan T. Lavavej videos/d1reportAllClassLayout und ein grep + Wort auf der Ausgabedatei zählen zu tun, aber es (a) erhöht mal enorm und (b) die Regex ist schwer zu 100% richtig zu bekommen.

Antwort

7

Ich machte eine one-line change an GCC, die es den Namen jeder Klassenvorlage ausdruckt, wie es es instanziiert. Sie können das C++ - Frontend cc1plus direkt ohne das -quiet-Flag aufrufen, um dasselbe für Funktionsvorlagen zu erhalten.

Ich bin noch nicht dazu gekommen das zu einer richtigen GCC Option zu machen, es ist nur ein Hack auf meinem eigenen Quellbaum. Ich denke darüber nach, es als Plugin zu implementieren, aber es steht nicht ganz oben auf meiner TODO-Liste.

+0

+1. Ich schlug vor, dass es ziemlich einfach sein sollte, jeden Open-Source-Compiler zu hacken, aber Sie haben es tatsächlich auf bestmögliche Weise bewiesen (indem Sie einen Patch geschrieben haben, der es tatsächlich tut). – abarnert

+0

Danke! Was wäre noch bequemer zu haben (ja, Scope Creep kommt!) Ist ein Protokoll aller Klassenvorlagen und die Anzahl ihrer Instanziierungen, anstatt nur die Gesamtzahl oder die gesamte Liste aller Instanziierungen. Vielleicht ist ein Perl-Skript, um das vollständige Build-Protokoll nachzubearbeiten, was ich versuchen sollte. – TemplateRex

+1

einfach die Ausgabe nach 'awk -F '<' '{Vorlagen [$ 1] ++} END {für (t in Vorlagen) print t, Vorlagen [t]}'' –

2

Es gibt natürlich keinen tragbaren Weg, dies zu tun.

Es gibt hacky Weisen, es für die meisten Compiler zu tun. Du hast bereits eins für MSVC gefunden. Für gcc können Sie wahrscheinlich gccxml verwenden. Für jeden Open-Source-Compiler (gcc oder clang) sollte es ziemlich einfach sein, Code an der Stelle der Instanziierung hinzuzufügen, die entweder zählt oder etwas protokolliert, das nach dem Kompilieren gefiltert werden kann.

Für Clang/LLVM, können Sie einfach ein Plugin erstellen, das die Instanziierung hakt, die viel sauberer ist, aber wahrscheinlich tatsächlich mehr Arbeit.

Ein Build mit Debug-Symbolen, keine Optimierung und keine Entfernung kann mit den verfälschten Namen jeder Instanziierung enden, nach der Sie suchen können. Einige Compiler (einschließlich gcc) werden jedoch immer mindestens einige Methoden inline, ob Sie sie wollen oder nicht. Wenn Sie bereit sind, Ihren Code zu ändern, können Sie es wahrscheinlich zwingen, out-of-line instantiations zu erzeugen, vielleicht so etwas wie folgt aus:

template<int N> struct fact { 
    enum { value = N * fact<N-1>::value }; 
    int *dummy() { return &fact<N-1>::value; } 
}; 
+0

Vielen Dank!Das Ändern von Code ist nicht wirklich eine Option, da 99% der instanziierten Klassenvorlagen von Boost.MPL und usw. stammen, und ich möchte auch eine saubere Anzahl von diesen haben. – TemplateRex

+0

Ich glaube, MSVC kann so eingestellt werden, dass alle Inlining- und Optimierungsfunktionen deaktiviert werden, was bedeutet, dass Sie eine Out-of-Line-Instantiierung für alles erhalten, aber ich denke nicht, dass ein anderer Compiler solche Einstellungen hat. – abarnert

1

Es ist ein Werkzeug von Steven Watanabe geschrieben, die verwendet werden können, zu zählen die Anzahl der Template-Instanziierungen. Sie können es erhalten here. Grundsätzlich wird der Code so geändert, dass bei jeder Instanziierung einer Klasse eine Compilerwarnung generiert wird und Sie den resultierenden Text beispielsweise mit Regex verarbeiten können.

+0

Danke, ich würde das ausprobieren. – TemplateRex

Verwandte Themen