Falscher zirkulärer Referenzfehler

8

Unser Team hat Delphi 6 schon viele Jahre benutzt und ist dann vor drei Jahren zu Delphi gewechselt. Bei beiden Versionen haben wir folgendes Problem: Häufig beschwert sich der Compiler über eine Einheit, die angeblich rekursiv verwendet wird . Diese Einheit ist eine 40k LOC-Einheit, die den Kern eines Projekts mit fast 1 Million LOC (Drittanbieter eingeschlossen) bildet.

Die Fehlermeldung ist falsch: ein vollständiger Build auf dem Projekt funktioniert immer . Leider sagt uns die Fehlermeldung nicht, wo der vermutete Zirkelbezug ist, nur der Name dieser Einheit. Manchmal kommt es sogar vor, dass gültige Fehlermeldungen 2-4 mal aufgelistet werden, bis das zirkuläre Referenzproblem "gefunden" ist. Der Compiler läuft hier eindeutig im Kreis. Aufgrund der Größe des Projekts ist es schwierig, das Problem manuell zu finden. Deshalb habe ich ein Werkzeug erstellt, das beweist, dass es wirklich keinen Zirkelbezug gibt (das Werkzeug erzeugt einen gerichteten Abhängigkeitsgraph der Einheiten und bestimmt die Kohärenzkomponenten in diesem Graphen - es gibt keine, außer wenn ich absichtlich etwas davon gebe in).

Dies betrifft nicht nur die F9-Kompilierung, sondern auch die Code-Vervollständigung / -Einsicht, die meistens nicht funktioniert. Manchmal funktioniert es, wenn ich ctrl-space ein zweites Mal drücke ...

Irgendwelche Ideen, wie wir das Problem isolieren oder sogar beheben können? Beachten Sie, dass es sehr schwierig sein wird, die 40k LOC-Einheit in kleinere zu teilen, weil sie etwa 15 große Klassen enthält, die im Interface-Bereich voneinander abhängen (ich weiß, dass es schlecht ist, aber trotzdem funktionieren sollte).

Aktualisieren
Wir refactorieren ständig, aber das ist eine schwierige Aufgabe, denn alles hängt von allem ab. Habe versucht, es über Schnittstellen zu umgehen, aber wir sprechen über einige Klassen mit 100 Methoden und Eigenschaften. Und es wäre langsamer.

Das Upgrade auf D2009 könnte eine Option sein, aber im Moment stecken wir fest mit D2006 (das Unicode-Zeug und das Preisschild sind zwei der Stopper hier). Frage ist eh, wenn es helfen würde da das Problem seit D6 da drin ist.

Über das Trimmen der uses-Klauseln haben wir dies häufig mit Icarus gemacht. Aber das hat bisher nicht geholfen. Wir sind jetzt auf 90 benutzerdefinierte Einheiten in der Benutzeroberfläche Abschnitt. Mit einem echten Zirkelbezug könnte das Problem jedoch in jeder Einheit auftreten. Auch versucht, alle Einheiten zum dpr hinzuzufügen.

Das Projekt teilt eine Menge Code mit anderen Projekten, und es gibt einige IFDEFs. Die Defines werden jedoch nicht in Projektoptionen, sondern über eine gemeinsame Include-Datei eingerichtet. Daher sollten alle Module die gleichen definieren. Außerdem tritt das Problem kurz nach einer vollständigen Neuerstellung auf, ohne zu einem anderen Projekt zu wechseln.

    
Werner Lehmann 24.05.2009, 14:31
quelle

9 Antworten

4

Ich werde wahrscheinlich dafür ablehnen. In D2005 hatte ich eine 10k Loc-Einheit (Datamodul), die nicht mehr kompiliert wurde. Musste einige Datensätze / Code zu einem anderen Datamodul trennen. Diese 10k-Einheit war und ist ein Durcheinander. Sie sollten wirklich erwägen, Code für andere Einheiten zu refactoring. Mein Modul ist seit D2005 / Separation noch schlechter gewachsen, aber es kompiliert immer noch in D2007. Also meine Antwort ist a) Refaktor und b) Upgrade auf D2009.

    
Tom 24.05.2009 21:30
quelle
2

Es scheint klar zu sein, dass dies auf einen kleinen Unterschied zwischen dem Hintergrund-Compiler und der realen Sache zurückzuführen ist. Sie können sich ansehen (QualityCentral), was zu diesem Thema bekannt ist.

Da Sie dies nicht explizit angegeben haben, sollten Sie auch unnötige Einheiten entfernen und Verwendungen soweit wie möglich in die Implementierung verschieben. Vielleicht könnte dein Werkzeug dabei helfen.

Und nur um sicher zu gehen, sollten Sie die Einheitenalias und Pfadeinstellungen überprüfen.

    
Henk Holterman 24.05.2009 16:01
quelle
2

Sie schreiben, dass ein vollständiger Build immer erfolgreich ist, aber kurz nach dem inkrementellen Build schlägt dieser Fehler fehl. Angenommen, Sie haben dies in der IDE festgestellt. Haben Sie versucht, den Befehlszeilencompiler dcc32 für inkrementelle Builds zu verwenden?

Wenn Sie es nicht mit dem Schalter "-Q" füttern (was wahrscheinlich die meisten Makefiles oder Skripte für Kommandozeilen-Builds tun), gibt es viele Informationen darüber aus, welche Dateien in welcher Reihenfolge kompiliert werden. Sie könnten entweder versuchen, einen inkrementellen Build zu erstellen, nachdem der Fehler in der IDE aufgetreten ist, oder Sie können eine Befehlszeile neben der IDE und Alt + Tab zum Kompilieren öffnen, ohne die Kompilierung in der IDE zu überspringen.

Ich gehe einfach davon aus, dass Sie mit dcc32 eine Möglichkeit haben, auf die eine oder andere Weise zu bauen - mit der Größe Ihres Projekts kann ich mir das nicht anders vorstellen.

    
mghie 25.05.2009 11:28
quelle
2

Wir haben regelmäßig ähnliche Probleme, und wir haben es nie geschafft (oder haben uns lange genug darum gekümmert), die genaue Ursache zu finden. Es scheint ein Problem in der Reihenfolge zu geben, in der Delphi die Einheiten beim Drücken von Strg-F9 kompiliert, was mit der tatsächlichen Abhängigkeitsreihenfolge der Einheiten nicht kompatibel ist.

  • Haben Sie versucht, "MyBigFatUnit.dcu" zu löschen, bevor Sie Strg-F9 drücken?
  • Haben Sie versucht, die Deklaration Ihrer Einheiten in Ihren dpr / dpk-Dateien neu zu ordnen, sodass die Einheiten in einer korrekten Kompilierreihenfolge angezeigt werden? (d. h. wenn Einheit B von Einheit A abhängt, sollte Einheit A zuerst in dpr / dpk erscheinen)
LeGEC 25.05.2009 14:30
quelle
0

Haben Sie noch andere Projekte, die Teile derselben Codebasis verwenden? Wenn Sie einen von ihnen unter verschiedenen Compilereinstellungen oder IFDEFs kompilieren, kann es bestimmte Dinge in einigen DCUs ändern, die zu einer zirkulären Abhängigkeit führen würden. Bei einem vollständigen Build werden alle DCUs neu erstellt und das Problem verschwindet.

    
Mason Wheeler 24.05.2009 15:30
quelle
0

Probieren Sie Icarus (kostenlos) von Peganza aus. Wenn Sie das Problem nicht wissen, versuchen Sie es mit dem Pascal Analyzer.

    
frogb 24.05.2009 15:55
quelle
0

Wir haben auch dieses Problem, auch mit einer ziemlich großen Codebasis.

Wir verwenden derzeit D2009, hatten aber dieses Problem mit allen früheren Versionen von Delphi.

Am häufigsten geschieht dies unmittelbar nach einer Aktualisierung von der Quellcodeverwaltung. Daher vermute ich, dass es im Delphi-Erstellungsprozess ein Zeitstempelproblem gibt.

In unserem Fall, wenn Ctrl-F9 fehlschlägt und den Zirkelverweis ausgibt, funktioniert im Allgemeinen eine zweite Strg-F9

    
Alistair Ward 26.05.2009 21:53
quelle
0

Eine Möglichkeit, mit der ich umgehen kann, ist, eine andere beliebige Datei im Projekt zu öffnen, diese Datei zu ändern, sie zu speichern und dann die inkrementelle Kompilierung erneut auszuführen. Überraschenderweise funktioniert das normalerweise.

Wir haben ein 4-MLOC-Projekt, bei dem das von Zeit zu Zeit auftaucht und diese "Lösung" funktioniert für mich.

    
Jonathan Morgan 10.02.2011 04:56
quelle
0

Ich habe das schon mal bekämpft, der Fehler ist meiner Erfahrung nach quasi legitim. Es ist eine ganze Weile her (der Fehler hat nichts mit der Version zu tun), aber meine Erinnerung an die Situation ist, dass es sich um eine Schleife handelt, in der sich ein Teil der Schleife in der Implementierung befindet.

Unit A verwendet B in der Implementierung. Einheit B verwendet A in der Schnittstelle. Wenn Sie B zuerst kompilieren, wird A aufgerufen, aber da der Aufruf von B in der Implementierung erfolgreich ist, ist es erfolgreich. Wenn Sie zuerst A kompilieren, dann ruft B auf, B dreht sich um und ruft nach A in der Schnittstelle, Boom. Solche Schleifen sind nur sicher, wenn beide Querverweise in der Implementierung sind.

Die Lösung besteht darin, die Dinge so zu gestalten, dass nur ein Minimum an Dingen in der Schnittstelle verwendet wird, und sicherzustellen, dass in diesen Einheiten nichts wie eine Schleife aussieht. Solange Sie Ihre Typdefinitionen von Einheiten mit Code getrennt halten, ist dies ziemlich einfach.

Der Fehler kommt und geht, je nachdem, was Sie tun, ist ein Kennzeichen dieses Problems, da es darauf ankommt, wie Sie in die Schleife kommen. Wenn Sie einen vollständigen Build erstellen, ist die Reihenfolge konsistent und Sie erhalten entweder 100% oder 0%, es ist nicht zufällig.

    
Loren Pechtel 10.02.2011 05:10
quelle

Tags und Links