2016-07-08 15 views
-1

Ich merke, dass Compilerfehler in Batches kommen. Wenn ich eine Marke mache, habe ich vielleicht 80 Fehler oder so viele. Dann, nachdem ich alle diese Fehler behoben habe, nachdem der letzte behoben ist, führe ich make aus und der Compiler kündigt einen weiteren Stapel von 100 Fehlern an. Dies geschieht mehrmals. Der Compiler scheint mehrere Runden oder Phasen zu durchlaufen und erzeugt am Ende jedes Satzes eine Reihe von Fehlern.Warum kommen Compilerfehler in Stapeln?

Beachten Sie, dass dies keine künstlichen Fehlergrenzen hat. fmax-errors ist standardmäßig 0 und das ist der Wert, den es hatte, als ich meine Kompilierung machte.

Was ist die Erklärung für dieses Verhalten?

Beachten Sie, dass ich in diesem Fall gcc verwende, aber ich habe andere Compiler festgestellt, die das gleiche tun.

+0

Klingt so, als müssten Sie an Ihren Tippgewohnheiten arbeiten. Und schreiben Sie auch nicht Tausende von Codezeilen zwischen den Kompilierungen. Schreiben Sie etwas kompilieren, schreiben Sie etwas kompilieren. Hinweis: Beginnen Sie am Anfang der Fehlerliste, nicht am Ende. vielleicht nur ein oder zwei reparieren und dann neu kompilieren. –

+0

@dwelch In diesem speziellen Projekt wurde ungewöhnlich viel Code geschrieben, bevor die Kompilierung aus idiosynkratischen Gründen versucht wurde. Normalerweise kompiliere ich mehr inkrementell. –

+0

und solche Probleme werden bei solchen Projekten, der Natur des Biests, passieren. Gleiches gilt für die Portierung eines großen Projekts von einem Ziel auf ein anderes. Sie müssen nur die Tausende von Fehlern einzeln oder zu einem bestimmten Zeitpunkt durcharbeiten. –

Antwort

1

Sie können nichts dagegen tun.

Denken Sie an eine c (++) Datei mit mehreren Funktionsdefinitionen. Der Compiler ist möglicherweise nicht in der Lage, den Modulquellcode nach einer fehlerhaften Funktionsimplementierung vollständig zu analysieren. Oft führen Fehler zu Mehrdeutigkeiten, die der Compiler nicht auflösen kann. Angenommen, Sie verpassen die schließenden Klammern einer Funktion. Wie soll der Compiler es zur weiteren Fehlerprüfung interpretieren? Nimm einfach an, dass die Klammern da sind? Oder nehmen wir an, die folgenden Funktionen sind geschachtelte Funktionen innerhalb der ersten und dass die schließende Klammer tatsächlich am Ende der Datei fehlt?

In der Praxis kümmere ich mich selten darum, denn wenn es nicht baut, lohnt es sich nicht, über das Verhalten des Programms nachzudenken. Sie müssen alle Fehler nacheinander durchgehen.

Ein Take eines Compiler-Entwicklers auf diesem wäre jedoch interessant.

+0

Das klingt plausibel, aber vage. Ich hoffe irgendwie auf eine konkretere Identifizierung, warum die Kompilierung an bestimmten Punkten aufhört und ihre Fehlerlieferung durchführt. –

+0

das ist im Grunde es die Datei wird linear analysiert, wenn Sie ein Semikolon in einer Zeile fehlt, die den Rest der Analyse von diesem Punkt nach vorne ändert, verpassen Sie eine schließende Klammer oder Klammer, etc. Der Parser macht, was Sie ihm gesagt haben, zu tun und diese Datei ohne ein kritisches Zeichen ist eine Gesamtmenge an Massenfehlern aus einer Analyseperspektive. –

+0

@dwelch Obwohl dieser Effekt auftritt, war in meinem Fall der letzte Fehler in den meisten Fällen kein Syntaxfehler, der die Ausklammerung oder den Bereich beeinträchtigte. –

0

In der Regel wird dies durch Syntaxfehler verursacht (im Gegensatz zu semantischen Fehlern).

Syntaxfehler können den Compiler verwirren. Genauer gesagt können sie dazu führen, dass sein interner Zustand nicht dem entspricht, was der Code sein soll. Das Ergebnis kann eine Kaskade scheinbar nicht zusammenhängender Fehlermeldungen sein.

Ein kleines Beispiel mit gcc (ähnliche Überlegungen werden wahrscheinlich andere Compiler anzuwenden):

#include <stdio.h> 
int main(void) 
    char s = "Hello, world"; 
    puts(s); 
} 

Dies hat zwei Fehler: eine fehlende { und einen falschen Typ für s (es muss char* sein, nicht char).

Ein wirklich cleverer Compiler könnte herausfinden, wo das fehlende { sein muss, schlagen vor, es an diesem Punkt hinzuzufügen, und weitermachen, um den Rest der Datei zu kompilieren, vorausgesetzt, dass es da ist. Keine Kritik an gcc gedacht, aber es ist nicht ganz so clever:

c.c: In function ‘main’: 
c.c:3:5: error: parameter ‘s’ is initialized 
    char s = "Hello, world"; 
    ^
c.c:4:5: error: expected declaration specifiers before ‘puts’ 
    puts(s); 
    ^
c.c:5:1: error: expected declaration specifiers before ‘}’ token 
} 
^ 
c.c:2:5: error: old-style parameter declarations in prototyped function definition 
int main(void) 
    ^
c.c:5:1: error: expected ‘{’ at end of input 
} 
^ 

Ohne die { eine Erklärung von char s; wäre tatsächlich syntaktisch gültig an diesem Punkt, wie ein alter Stil (pre-ANSI) Parameterdeklaration. GCC (etwas vernünftig) geht davon aus, dass es das ist, und beschwert sich über den Initialisierer - aber nicht über den falschen Typ des Initialisierers. Es diagnostiziert den Aufruf puts als etwas, das nicht in einer alten Parameterliste angezeigt werden sollte, und schließlich beschwert über die fehlende { am Ende der Datei.

Da es den beabsichtigten Kontext der Deklaration s nicht kannte, diagnostiziert es die anderen Probleme nicht ordnungsgemäß.

Nachdem wir die { an der richtigen Stelle hinzufügen, gcc in der Lage, korrekt die verbleibenden Probleme zu diagnostizieren:

c.c: In function ‘main’: 
c.c:3:14: warning: initialization makes integer from pointer without a cast [enabled by default] 
    char s = "Hello, world"; 
      ^
c.c:4:5: warning: passing argument 1 of ‘puts’ makes pointer from integer without a cast [enabled by default] 
    puts(s); 
    ^
In file included from c.c:1:0: 
/usr/include/stdio.h:695:12: note: expected ‘const char *’ but argument is of type ‘char’ 
extern int puts (const char *__s); 
      ^

In komplexeren Fällen Sie mehrere Pässe benötigen eine saubere Zusammenstellung zu erhalten. Auf der anderen Seite ist der Compiler manchmal in der Lage, Daten wiederherzustellen und weiter zu analysieren - aber die Syntax von C ist so, dass solche Wiederherstellungsversuche sehr oft fehlschlagen.

Eine Faustregel: Wenn der Compiler einen Syntaxfehler meldet, beheben Sie den ersten gemeldeten Syntaxfehler und kompilieren Sie. Wenn vor dem ersten Syntaxfehler mehrere nicht syntaktische Fehler auftreten, können Sie sie auch beheben. Alle Diagnosemeldungen, die einem Syntaxfehler folgen, sind nicht vertrauenswürdig. (Das ist nicht 100% wahr; manchmal können solche Nachrichten nützlich sein, so dass sie auf ein Problem zeigen, das Sie beheben können, und beheben Sie es vor dem erneuten Kompilieren.)

Dies erfordert, zu wissen, wie Syntaxfehlermeldungen zu erkennen sind. Einige Compiler enthalten möglicherweise das Wort "Syntax" in der Fehlermeldung, aber wie Sie sehen können gcc nicht. Wenn gcc sagt Ihnen, dass es erwartet ein bestimmtes Element, das ist eine Syntax-Fehlermeldung.

Eine andere Sache, auf die Sie achten sollten, ist, dass die Syntaxfehlermeldung möglicherweise nicht auf das tatsächliche Problem zeigt, wie in diesem Fall. Sie müssen möglicherweise einige Zeilen (oder viele Zeilen) von dem Punkt, an dem der Fehler gemeldet wird, nachsehen, um zu sehen, was den Fehler verursacht hat. Ein kleiner Fehler in einer C-Quelldatei kann ihn in etwas verwandeln, das immer noch syntaktisch Wert ist, oder fast gültig, aber mit einer ganz anderen Bedeutung. Fehlende Semikolons sind eine häufige Ursache für diese Art von Problem. Nicht übereinstimmende Kommentartrennzeichen sind ein anderes.

Andere Tools, wie IDEs oder Editoren mit Syntaxhervorhebung, können helfen, Syntaxfehler vor dem Kompilieren zu erkennen.