Dies begann als SO-Frage, aber ich erkannte, dass es ziemlich unkonventionell ist und basierend auf der tatsächlichen Beschreibung auf den Websites möglicherweise besser für Programmierer geeignet ist, da die Frage viel konzeptionelles Gewicht hat.
Ich habe Clang LibTooling gelernt und es ist ein sehr leistungsfähiges Tool, das in der Lage ist, das gesamte " Nitty Gritty " des Codes auf freundliche Weise, dh auf semantische Weise und auch nicht durch Vermutung, aufzudecken. Wenn clang Ihren Code kompilieren kann, ist clang sicher über die Semantik jedes einzelnen Zeichens in diesem Code.
Lassen Sie mich jetzt einen Moment zurücktreten.
Es gibt viele praktische Probleme, die auftreten, wenn man sich mit der Metaprogrammierung von C ++ - Vorlagen beschäftigt (und insbesondere, wenn man sich über Vorlagen hinaus in das Gebiet cleverer, wenn auch erschreckender Makros wagt). Um ehrlich zu sein, sind viele der üblichen Verwendungszwecke von Vorlagen für viele Programmierer, auch für mich, etwas erschreckend.
Ich denke, ein gutes Beispiel wären Zeichenfolgen zur Kompilierungszeit . Dies ist eine Frage, die mittlerweile über ein Jahr alt ist, aber es ist klar, dass C ++ ab sofort dies für bloße Sterbliche nicht einfach macht. Das Betrachten dieser Optionen reicht zwar nicht aus, um Übelkeit für mich auszulösen, aber ich bin mir nicht sicher, ob ich magischen, maximal effizienten Maschinencode erstellen kann, der zu jeder ausgefallenen Anwendung passt, die ich für meine Software habe.
Ich meine, seien wir ehrlich, Leute, Saiten sind ziemlich einfach und grundlegend. Einige von uns möchten nur einen bequemen Weg, um Maschinencode auszugeben, bei dem bestimmte Zeichenfolgen wesentlich stärker "eingebrannt" sind, als dies beim einfachen Codieren der Fall ist. In unserem C ++ - Code.
Geben Sie clang und LibTooling ein, wodurch der abstrakte Syntaxbaum (AST) des Quellcodes verfügbar gemacht wird und eine einfache benutzerdefinierte C ++ - Anwendung die korrekte und zuverlässige Bearbeitung des Rohquellcodes (mithilfe Rewriter
) zusammen mit einem umfangreichen semantischen objektorientierten Modell von allem im AST ermöglicht. Es behandelt viele Dinge. Es kennt die Makroerweiterungen und lässt Sie diesen Ketten folgen. Ja, ich spreche von Transformation oder Übersetzung von Quellcode zu Quellcode.
Meine grundlegende These hier ist, dass Clang es uns jetzt ermöglicht, ausführbare Dateien zu erstellen, die selbst als ideale benutzerdefinierte Präprozessorstufen für unsere C ++ - Software fungieren können, und wir können diese Metaprogrammierstufen mit C ++ implementieren. Wir sind lediglich durch die Tatsache eingeschränkt, dass diese Phase Eingaben vornehmen muss, die gültigen C ++ - Code sind, und als Ausgabe mehr gültigen C ++ - Code erzeugen muss. Plus alle anderen Einschränkungen, die Ihr Build-System anwendet.
Die Eingabe muss zumindest sehr nahe am gültigen C ++ - Code liegen, denn schließlich ist clang das Compiler-Frontend, und wir stöbern nur herum und sind kreativ mit seiner API. Ich weiß nicht, ob es eine Möglichkeit gibt, eine neue zu verwendende Syntax zu definieren, aber wir müssen natürlich die Methoden entwickeln, um sie richtig zu analysieren und dem Clang-Projekt hinzuzufügen, um dies zu tun. Mehr zu erwarten bedeutet, etwas im Clang-Projekt zu haben, das außerhalb des Rahmens liegt.
Kein Problem. Ich würde mir vorstellen, dass einige No-Op-Makrofunktionen diese Aufgabe übernehmen können.
Eine andere Möglichkeit, das zu betrachten, was ich beschreibe, besteht darin, Metaprogrammierkonstrukte mit Laufzeit-C ++ zu implementieren, indem der AST unseres Quellcodes (dank clang und seiner API) manipuliert wird, anstatt sie mit den eingeschränkteren Tools zu implementieren, die in der Sprache selbst verfügbar sind. Dies hat auch deutliche Vorteile für die Kompilierungsleistung (vorlagenintensive Header verlangsamen die Kompilierung proportional zu der Häufigkeit, mit der Sie sie verwenden. Viele kompilierte Inhalte werden dann sorgfältig abgeglichen und vom Linker weggeworfen).
Dies geht jedoch zu Lasten der Einführung von ein oder zwei zusätzlichen Schritten in den Erstellungsprozess und auch der Anforderung, eine (zugegebenermaßen) etwas ausführlichere Software (aber zumindest eine einfache Laufzeit-C ++) als Teil unseres Tools zu schreiben .
Das ist nicht das ganze Bild. Ich bin mir ziemlich sicher, dass durch das Generieren von Code, der mit Kernsprachenfunktionen äußerst schwierig oder unmöglich ist, ein viel größerer Funktionsbereich zur Verfügung steht. In C ++ können Sie eine Vorlage oder ein Makro oder eine verrückte Kombination aus beiden schreiben, aber in einem Clang-Tool können Sie Klassen und Funktionen auf JEDE Weise ändern, die Sie mit C ++ zur Laufzeit erreichen können , während Sie vollen Zugriff auf den semantischen Inhalt haben. Neben Vorlagen und Makros und allem anderen.
Ich frage mich also, warum das nicht schon alle machen. Ist es so, dass diese Funktionalität von clang so neu ist und niemand mit der riesigen Klassenhierarchie von clangs AST vertraut ist? Das kann es nicht sein.
Vielleicht unterschätze ich die Schwierigkeit nur ein wenig, aber die "Manipulation von Zeichenfolgen zur Kompilierungszeit" mit einem Clang-Tool ist fast kriminell einfach. Es ist ausführlich, aber wahnsinnig einfach. Alles, was benötigt wird, sind eine Reihe von No-Op-Makrofunktionen, die den tatsächlichen realen std::string
Operationen zugeordnet sind. Das Clang-Plugin implementiert dies, indem es alle relevanten No-Op-Makroaufrufe abruft und die Operationen mit Zeichenfolgen ausführt. Dieses Tool wird dann als Teil des Erstellungsprozesses eingefügt. Während der Erstellung werden diese No-Op-Makrofunktionsaufrufe automatisch in ihren Ergebnissen ausgewertet und dann als einfache alte Zeichenfolgen zur Kompilierungszeit wieder in das Programm eingefügt. Das Programm kann dann wie gewohnt kompiliert werden. Tatsächlich ist dieses resultierende Programm daher auch viel portabler, da kein ausgefallener neuer Compiler erforderlich ist, der C ++ 11 unterstützt.