Unser DMS Software Reengineering Toolkit mit seinem C++ 11 Frontend könnte dazu verwendet werden; Derzeit macht es das nicht von der Stange. DMS wurde entwickelt, um benutzerdefinierte Werkzeugkonstruktionen für beliebige Quellsprachen bereitzustellen. Es enthält vollständige Parser, Namensauflöser und verschiedene Flussanalysatoren zur Unterstützung der Analyse sowie die Möglichkeit, Quellen-zu-Quell-Transformationen auf dem Code basierend auf Analyseergebnissen anzuwenden.
Im Allgemeinen möchten Sie eine statische Analyse, die bestimmt, ob jede Berechnung (Ergebnis, es kann mehrere sein, betrachten Sie nur "x ++") verwendet wird oder nicht. Für jede nicht verwendete Berechnung möchten Sie die nicht verwendete Berechnung entfernen und die Analyse wiederholen.Aus Effizienzgründen möchten Sie eine Analyse durchführen, die alle (Punkte der) Verwendung der Ergebnisse nur einmal bestimmt; Dies ist im Wesentlichen eine Datenflussanalyse. Wenn die Verwendungsmenge eines Berechnungsergebnisses leer ist, kann dieses Berechnungsergebnis gelöscht werden (beachten Sie, dass das Löschen des "x ++" -Werteergebnisses "x ++" verlassen kann, da das Inkrement immer noch benötigt wird!) Und die Verwendungsmengen von Berechnungen, von denen es abhängt kann angepasst werden, um Referenzen von der gelöschten zu entfernen, wodurch möglicherweise mehr Entfernungen verursacht werden.
Um diese Analyse für jede Sprache durchzuführen, müssen Sie in der Lage sein, Ergebnisse zu verfolgen. Für C (und C++) kann das ziemlich hässlich sein; Es gibt "offensichtliche" Verwendungen, bei denen ein Berechnungsergebnis in einem Ausdruck verwendet wird und wo es einer lokalen/globalen Variablen zugewiesen wird (die anderswo verwendet wird), und es gibt indirekte Zuweisungen durch Zeiger, Objektfeldaktualisierungen über beliebige Umwandlungen usw. Um diese Effekte zu kennen, muss Ihr Tool zur Analyse des toten Codes in der Lage sein, das gesamte Softwaresystem zu lesen und Datenflüsse darüber zu berechnen.
Um sicherzugehen, möchten Sie, dass diese Analyse konservativ ist, z. B. wenn das Werkzeug keinen Beweis dafür hat, dass ein Ergebnis nicht verwendet wird, dann muss davon ausgegangen werden, dass das Ergebnis verwendet wird; Sie müssen dies oft mit Zeigern (oder Array-Indizes, die nur verkappte Zeiger sind) tun, weil Sie im Allgemeinen nicht genau bestimmen können, wo ein Zeiger "zeigt". Man kann offensichtlich ein "sicheres" Werkzeug aufbauen, indem man annimmt, dass alle Ergebnisse verwendet werden: -} Sie werden auch mit manchmal sehr konservativen aber notwendigen Annahmen für Bibliotheksroutinen enden, für die Sie die Quelle nicht haben. In diesem Fall ist es hilfreich, einen Satz vorberechneter Zusammenfassungen der Nebeneffekte der Bibliothek zu haben (z. B. hat "strcmp" keine, "sprintf" überschreibt einen bestimmten Operanden, "push_back" ändert sein Objekt ...). Da Bibliotheken ziemlich groß sein können, kann diese Liste ziemlich groß sein.
DMS im Allgemeinen kann analysieren und gesamte Quellcode-Basis, Symboltabellen erstellen (also weiß, welche Bezeichner local/global und ihre genaue Art sind), Kontrolle und lokale Datenflussanalyse, erstellen Sie eine lokale "Nebenwirkungen" Zusammenfassung pro Funktion , erstellen Sie ein Call-Diagramm und globale Nebenwirkungen, und führen Sie eine globale Punkt-zu-Punkt-Analyse durch und stellen Sie diese "berechnete verwendete" Information mit entsprechendem Konservatismus zur Verfügung.
DMS wurde verwendet, um diese Berechnung auf C-Code-Systemen von 26 Millionen Zeilen Code (und ja, das ist eine sehr große Berechnung; es dauert 100 GB VM zu laufen). Wir haben den Dead Code Elimination Teil nicht implementiert (das Projekt hatte einen anderen Zweck), aber das ist einfach, sobald Sie diese Daten haben. DMS hat die Eliminierung des toten Codes bei großen Java-Codes mit einer konservativeren Analyse durchgeführt (z. B. "keine Verwendung eines Identifizierers", was bedeutet, dass Zuweisungen an den Identifizierer tot sind), was eine überraschende Menge an Codeentfernung in vielen realen Codes verursacht.
Der C++ - Parser von DMS erstellt derzeit Symboltabellen und kann eine Kontrollflussanalyse für C++ 98 durchführen, wobei C++ 11 in der Nähe ist. Wir benötigen noch eine lokale Datenflussanalyse, was ein wenig Aufwand ist, aber die globalen Analysen existieren bereits im DMS und stehen für diesen Effekt zur Verfügung. (Die "keine Verwendung eines Bezeichners" ist leicht aus den Symboltabellendaten verfügbar, wenn Sie eine konservativere Analyse nicht ablehnen).
In der Praxis möchten Sie nicht, dass das Tool nur die Daten stillschweigend abruft; einige könnten tatsächlich Berechnungen sein, die Sie trotzdem beibehalten möchten. Was das Java-Tool tut, ist zwei Ergebnisse zu produzieren: eine Liste der toten Berechnungen, die Sie inspizieren können, um zu entscheiden, ob Sie es glauben, und eine dead-Code entfernte Version des Quellcodes. Wenn Sie den Bericht über den toten Code glauben, behalten Sie die Version mit entferntem Code bei. Wenn Sie eine "tote" Berechnung sehen, von der Sie denken, dass sie nicht tot sein sollte, ändern Sie den Code so, dass er nicht tot ist, und führen Sie das Tool erneut aus. Mit einer großen Codebasis kann die Überprüfung des Berichts über den toten Code selbst ein Versuch sein; Woher weiß "you", ob ein gewisser, scheinbar toter Code nicht von "jemand anderem" in Ihrem Team bewertet wird? (Versionskontrolle kann verwendet werden, um wiederherzustellen, wenn Sie goof!)
Ein wirklich kniffliges Problem, das wir nicht (und kein Werkzeug, das ich kenne) behandeln, ist "toter Code" in Anwesenheit von bedingten Kompilierung.(Java hat dieses Problem nicht; C hat es in Pik, C++ Systeme viel weniger). Das kann wirklich böse sein. Stellen Sie sich eine Bedingung vor, in der Arm bestimmte Nebenwirkungen hat und der andere Arm verschiedene Nebenwirkungen hat, oder ein anderer Fall in dem der C++ - Compiler von GCC interpretiert wird und der andere Arm von MS interpretiert wird und die Compiler sich nicht einig sind, was die Konstrukte tun (Ja, die C++ - Compiler stimmen in dunklen Ecken nicht überein). Bestenfalls können wir hier sehr konservativ sein.
CLANG verfügt über eine gewisse Fähigkeit zur Durchflussanalyse; und eine gewisse Fähigkeit, Quelltransformationen durchzuführen, so dass es dazu gezwungen werden könnte. Ich weiß nicht, ob es eine globale Flow/Point-to-Analyse machen kann. Es scheint eine Tendenz zu einzelnen Kompilierungseinheiten zu haben, da es hauptsächlich eine Kompilierungseinheit kompiliert.
[Interessantes Gespräch] (http://www.youtube.com/watch?v=C-_dw9iEzhA) auch – soandos