Analysetool für statischen C++-Code: Finden Sie die Diamanten in einem großen Quellcode

( Verwandte SO-Frage .)

Bedenken Sie, dass es eine sehr große Klassenhierarchie gibt, von Dutzenden oder sogar Hunderten von Klassen. Das Vererbungsdiagramm ist auch sehr komplex (doxygen kann es ohne halbseitengroße Pfeile nicht darstellen :-) ). Und hier kommt das gefürchtete Diamantproblem. Ich suche nach einem Weg, alle Diamanten zu finden.

Etwa so:

Die roten Vererbungspfeile mit Bleistift müssen virtuell sein.  Das Finden der Diamanten ist für den ersten Platz einfach.

Hier müssen die rot markierten Vererbungspfeile virtuell sein. In einer so einfachen Struktur ist es leicht, alle zu finden, aber nicht in einer viel größeren.

Das Finden aller Diamanten scheint ein leicht automatisierbares Graph-Walking-Problem zu sein. Es würde mich wundern, wenn es nicht schon eine Lösung für die Aufgabe gäbe.

Die Frage ist bereits ein Tool für eine Aufgabe vorhanden?

Meine Wette wäre, dass es mit CppDepend möglich ist , aber ich arbeite in einer neuen Firma und habe keine Lizenz mehr. Außerdem habe ich keine Codebasis zum Testen. Sicherlich gibt es keine eingebaute Funktion, um Diamanten zu finden (ich höre davon das erste Mal), aber CppDepends unterstützt CQLinq , eine Abfragesprache, die es ermöglichte, jede meiner Aufgaben zu lösen. Holen Sie sich die 14-Tage-Testversion. Fragen Sie vielleicht support@cppdepend.com, ob eine solche Abfrage möglich wäre. Es ist kommerziell @ 500 USD.
Wie definieren Sie in diesem Zusammenhang einen Diamanten – eine einzelne Klasse, die von mehreren Klassen abgeleitet ist, die wiederum von einer einzelnen Klasse abstammen, bei wie vielen Entfernungen? Kann sie auch von anderen Klassen erben? Konzeptionell leiten sich alle Klassenobjekte von einer einzigen Klasse ab (dh: Klasse oder Objekt).
@SteveBarnes Das Klassenvererbungsdiagramm ist ein DAG (gerichteter azyklischer Graph). Eine Raute ist ein mehrfach verbundener minimaler Untergraph dieses DAG. Beispielsweise ist BS-BCA-BCS-T4-BT4-BI4 eine Raute. In C++ gibt es (konzeptionell) keine "höchste Klasse". Ein Objekt ist in C++ eine Instanz einer Klasse, sie haben nichts mit diesem Problem zu tun, es geht nur um die Klassen.

Antworten (2)

Sie haben zwei Probleme zu lösen:

  • Abrufen des Vererbungsdiagramms über eine große C++-Anwendung
  • Entdeckung der Diamanten

Der erste Teil ist komplex, da das Parsen von C++ zum genauen Abrufen dieser Vererbungsinformationen schwierig ist (C++ selbst ist wahnsinnig schwer zu parsen, dann haben Sie die Komplikationen von Präprozessorbedingungen, Include-Dateien, Makros und Vorlagen). Dazu benötigen Sie ein vollständiges C++-Frontend und einen organisierten Angriff, um die Vererbungsinformationen zu sammeln.

Unser DMS Software Reengineering Toolkit mit seinem C++-Frontend kann verwendet werden, um diese Art von Informationen zu extrahieren. Sie können DMS so konfigurieren, dass es alle Ihre Kompilierungseinheiten analysiert und eine Namens-/Typauflösung durchführt; Dies übernimmt die gesamte Vorverarbeitung / Vorlagenauflösung und erzeugt für jede Kompilierungseinheit sowohl ASTs für das Programm (die Sie für diese Aufgabe nicht benötigen) als auch zugängliche Symboltabellen, die Deklarationen von Klassen und gewünschten A-Vererbungen enthalten -von-B-Informationen. Ein einfacher Symboltabellen-Scan kann die Vererbungsinformationen für jede Kompilationseinheit erzeugen.

Anschließend müssen Sie diese Informationen zusammenstellen, um ein Vererbungsdiagramm für Ihr System zu erhalten. Es sollte offensichtlich sein, dass Sie den Vererbungsgraphen buchstäblich erstellen möchten.

Mit diesem Diagramm ist die Entdeckung von Diamanten im Grunde einfach:

  1. Erstellen Sie für jeden Knoten ein leeres Hash-Set von Kindern, das den Pfad zum Kind speichert
  2. Aufzählen und Aufzeichnen aller Pfade von jedem Knoten zu seinen Kindern mithilfe einer Bottom-up-Aufzählung von Vererbungspfaden (leicht zu implementieren mit einer Tiefensuche)
  3. Jedes Mal, wenn Sie zweimal auf ein Kind von einem Knoten stoßen, enthält das Hash-Set die Pfade zu diesem Kind; zwei Pfade -> Diamant
  4. Markieren Sie diesen Knoten mit einer Raute, um zu vermeiden, dass alle Unterpfade erneut aufgelistet werden

Sie können diesen Diamond-Finder mit anderer Software als DMS implementieren, aber Sie könnten auch die interne prozedurale Programmiersprache von DMS verwenden, wodurch der Schritt vermieden würde, der die Vererbungsinformationen exportiert.

Zusammenfassung:

  • DMS mit C++-Frontend parst Code genau
  • Es können rohe Vererbungsinformationen pro Kompilationseinheit gesammelt werden
  • Sätze solcher Daten liefern ein Vererbungsdiagramm
  • Der Algorithmus zum Finden von Diamanten ist ziemlich einfach zu codieren.

Da DMS das Produkt meines Unternehmens ist, verstehen Sie dies nicht als Empfehlung, sondern lediglich als Hinweis, dass DMS existiert und die Aufgabe von OP erfüllen kann.

Ich denke, Sie sind ein guter Mann. Die SO tut dies, weil sie sonst von Spam überflutet würden. Obwohl ich ein Open-Source-Fan bin, ist es nicht gegen die Programmierer, die versuchen, ihre wirklich wunderbaren Produkte zu verkaufen, es ist gegen den Machtmissbrauch der großen Unternehmen. Ich hoffe, dass die Softwarerecs SE in diesem Sinne leichter ist.
Haben Sie jemals daran gedacht, Eclipse/msvs/anything-Plugins aus Ihren Tools zu erstellen?
@peterh: (Danke für den Vertrauensbeweis). In Bezug auf Eclipse-Plugins: wir tun; derzeit sind sie als spezialisierte COBOL-Analyse-Plugins in IBMs gebogener Version von Eclipse namens "RDz" verfügbar; Wir taten dies aus sehr komplizierten geschäftlichen Gründen, einschließlich der sogenannten "Eclipse-Kompatibilität", und waren nicht allzu erfreut, als IBM uns sagte, wie sich RDz von Mainstream-Eclipse unterscheidet. Wir gehen davon aus, dass wir eines Tages die breitere Palette von Maschinen anschließen werden, um in den Schatten zu stellen, aber das wird dieses Jahr nicht passieren.

Sie können auch CppDepend ausprobieren , das viele Funktionen bezüglich der Abhängigkeiten und eine Code-Abfragesprache bietet, um Ihre Abhängigkeitsregeln einfach zu erstellen.