Anfängerprogrammierer sind frustriert über das Fehlen eines Glossars mit Compilerfehlern

66

Ein Freund meiner Familie bat mich um ein wenig Hilfe, während er das Programmieren lernt (in der C-Sprache). Während des Gesprächs äußerte er sich frustriert darüber, dass es ihm schwerfällt, die Fehlermeldungen zu verstehen, die ihm sein Compiler (GCC) gibt, wenn er Fehler macht. Er versteht nicht alle verwendeten Begriffe, und manchmal ist es ihre Kombination, die er nicht versteht. Er fragte mich: "Warum enthält die Compiler-Dokumentation keine längeren Erklärungen der Fehlermeldungen?" - und ich hatte keine gute Antwort für ihn.

Ich selbst - als erfahrener Programmierer - bin sehr selten in dieser Situation, aber diese seltenen Vorkommnisse kommen vor - eine exotische Fehlermeldung, die ich vorher nicht erlebt hatte. Ich komme mit der Suche nach der Fehlermeldung in einer Suchmaschine zurecht, aber anscheinend funktioniert das bei ihm nicht immer - zumal die Fehler, auf die er stößt, häufiger sind und in mehreren Fällen auftreten, die er nur schwer mit seinen in Verbindung bringen kann besitzen.

Wie sollte ein unerfahrener Programmierer die Herausforderung des Verstehens von Compilerfehlermeldungen angehen? Insbesondere mit der Kombination von C und GCC?

einpoklum
quelle
7
"Also, wie sollte ein unerfahrener Programmierer die Herausforderung des Verstehens von Compilerfehlermeldungen angehen?" / sarcasm Die erste Fähigkeit, die benötigt wird, besteht darin, in der Lage zu sein, jedes Bit aus der Compiler-Nachricht zu lesen, einschließlich, es mit dem genauen Kontext in Beziehung zu setzen. / Sarkasmus aus. Es stellt sich selten heraus, dass es sich um einen Fehler oder einen Fehler im Compiler handelt.
Donnerstag,
10
@MasonWheeler: Ein Anfänger wählt häufig nicht den Compiler aus, der während des Trainings verwendet werden soll. Und GCC ist ein gemeinsamer Nenner vieler, vieler Systeme ...
einpoklum
24
Wenn es zu GCC C ++ - Vorlagenfehlern kommt, finde ich, wenn ich nach "Fehler <Datei: Zeile>" aufhöre zu lesen und die Quelldatei (en) studiere, finde ich den Fehler schneller, mit dem zusätzlichen Nebeneffekt, dass meine Vernunft gewahrt bleibt, als wenn ich den von GCC angegebenen Fehler lese .....
mattnz
18
Die Lösung liegt auf der Hand: Verwenden Sie einen Compiler mit weniger verwirrender Ausgabe. Ich schlage rmcc vor . Es wird gedruckt Yes.oder No.hängt davon ab, ob Ihr Code kompiliert wurde oder nicht. Beugt sofort der Frustration vor, lange und sinnlose Nachrichten nicht zu verstehen!
Pipe
21
C ist keine gute Sprache für Anfänger - und Sie sind auf einen der Gründe gestoßen. Davon abgesehen tendiert Clang dazu, viel bessere Fehler anzubieten, die auch Anfänger ansprechen könnten.
Theodoros Chatzigiannakis

Antworten:

164

Einige nützliche Techniken:

  • Einschalten -Wallund -Werror. Es mag uninteressant erscheinen, wenn Sie mit der Entschlüsselung von Fehlermeldungen zu kämpfen haben, um noch mehr Fehlermeldungen zu erstellen. Die Warnungen sind jedoch in der Regel leichter zu verstehen und näher an der eigentlichen Ursache des Problems, und das Ignorieren kann zu schwer verständlichen Fehlern führen .
  • Versuchen Sie einfach, den ersten Fehler in der Liste zu beheben. Oft verschmelzen die Fehler miteinander, was dazu führt, dass spätere Fehlermeldungen keine wirklichen Fehler sind. Beheben Sie eine und kompilieren Sie neu. Sie können mehrere Fehlermeldungen besser beheben, wenn Sie mehr Erfahrung sammeln.
  • Verwenden Sie die neueste Compiler-Version. C ist eine extrem stabile Sprache. Daher besteht ein großer Teil der Verbesserungen in neueren Compilern nicht darin, Sprachfunktionen hinzuzufügen, sondern die Entwicklererfahrung zu verbessern, einschließlich besserer Fehlermeldungen. Viele weit verbreitete Linux-Distributionen haben standardmäßig sehr alte Versionen von gcc.
  • Inkrementell programmieren. Versuchen Sie nicht, eine Tonne Code zu schreiben, bevor Sie kompilieren. Schreiben Sie den kleinstmöglichen Betrag, der noch kompiliert werden kann. Wenn Sie seit der letzten sauberen Kompilierung nur eine Zeile geändert haben, ist es viel einfacher, herauszufinden, in welcher Zeile sich das eigentliche Problem befindet.
  • Schreiben Sie Komponententests. Dadurch können Sie sicherer Änderungen am Refactoring vornehmen, wenn Sie Kompilierungsfehler beheben.
Karl Bielefeldt
quelle
23
Eine gute IDE kann die Erfahrung auch erheblich verbessern, indem z. Fehler werden rot unterstrichen.
BlueRaja - Danny Pflughoeft
86
"Programmieren Sie inkrementell. Versuchen Sie nicht, vor dem Kompilieren eine Tonne Code zu schreiben. Schreiben Sie die kürzest mögliche Menge, die noch kompiliert werden kann. Wenn Sie seit der letzten sauberen Kompilierung nur eine Zeile geändert haben, ist das viel einfacher herauszufinden welche Zeile enthält das eigentliche Problem. " Das, so sehr das. Die meisten IDEs warnen Sie auch, wenn Sie Code schreiben, der nicht kompiliert werden kann, und markieren die Fehler.
Polygnome
4
@einpoklum: Unterschätze die dritte Option nicht; Compiler-Fehlermeldungen haben sich stark verbessert. Verwenden Sie in ähnlicher Weise mehrere Compiler (z. B. gcc und clang) - Fängt mehr Fehler / Warnungen ab, und einer von ihnen verfügt möglicherweise über eine bessere Diagnose für ein bestimmtes Problem als der andere.
Mat
19
@einpoklum: Schreiben Dinge mehr inkrementell ist sehr genau das Richtige, vor allem für Anfänger. Wenn Sie der Meinung sind, dass "kurze Programmieraufgaben" nicht schrittweise ausgeführt werden können, indem Sie sie in mehrere kleine Funktionen aufteilen und einzeln implementieren und kompilieren, sollten Sie versuchen, diese Fähigkeiten für sich selbst zu verbessern.
Doc Brown
4
Ein Trick, der mir geholfen hat: Wenn in der Fehlermeldung Zeile N erwähnt wird, überprüfen Sie Zeile N-1. Wenn in Zeile 17 ein Semikolon fehlt, wird in der Fehlermeldung angezeigt, dass ein Fehler in Zeile 18 aufgetreten ist. Dies liegt daran, dass der Compiler ein Semikolon erwartet hat, in der nächsten Zeile jedoch einen anderen Fehler aufgetreten ist.
user2023861
56

Ihr Freund braucht kein Glossar. Ein Glossar hilft ihm nicht. Was er braucht, ist eine bessere Intuition darüber, was zu tun ist, wenn Compilerfehler auftreten.

C-Compiler-Fehler sind nicht so intuitiv wie beispielsweise C # -Compiler-Fehler, und zwar aus vielen Gründen, die in erster Linie mit der "Nähe zum Metall" von C zu tun haben empfangen kann nichts mit dem eigentlichen Problem zu tun haben. Im Gegensatz zu C # oder Java, bei denen eine Fehlermeldung in der Regel eine genaue Codestelle und ein genaues Problem aufweist, sind Fehler in C wahrscheinlich zahlreich und weit verbreitet.

Ein Beispiel hierfür ist "Semikolon erwartet" oder eine beliebige Anzahl von Syntaxfehlern, die darauf hinweisen, dass der Parser an etwas hängengeblieben ist (nicht unbedingt ein Semikolon). Oder so etwas wie "Unerwartete Vorwärtsdeklaration", ein Fehler, der, wenn ich ihn sehe, ausnahmslos bedeutet, dass ich in einer meiner .h-Dateien eine falsche Großschreibung vorgenommen habe, aber nicht auf die .h-Datei als Ursache des Problems hinweist.

Die Strategie Ihres Freundes sollte nicht darin bestehen, das Muster mit einer Liste von Fehlern und Lösungen abzugleichen. es sollte sein, die Syntax und Spezifikation der C-Sprache gut genug zu verstehen, um herauszufinden, was das eigentliche Problem ist.

Robert Harvey
quelle
17
Nein. Sie sollten die Sprache gut genug kennen, um zu wissen, dass Sie keinem numerischen Ausdruck, sondern nur einer Variablen zuordnen können. Sie müssen nicht wissen, was ein Wert überhaupt ist, weshalb sie das in Anfängerkursen nicht unterrichten.
Robert Harvey
18
Im Wesentlichen ja. Aber praktisch ist das nicht möglich. Ich mache das schon sehr lange und bekomme immer noch obskure Compiler-Fehlermeldungen, wenn ich ein C-Programm schreibe. Ich lese diese Botschaften selten und versuche sie zu verstehen. Stattdessen schaue ich, wohin die Fehlermeldung zeigt, und da ich weiß, wie die grundlegende Syntaxstruktur eines C-Programms aussehen soll, kann ich das Problem relativ schnell erkennen, ohne Zeit damit zu verbringen, Fehlermeldungen zu entziffern.
Robert Harvey
36
Anders ausgedrückt, das Verlangen eines Glossars zum Verständnis von Compilerfehlern ist ein bisschen wie das Lesen des Wörterbuchs, um die englische Sprache zu verstehen. das ist nicht ganz so wie es funktioniert. Sie lernen und verstehen Englisch, indem Sie es lesen und schreiben und nicht das Wörterbuch lesen.
Robert Harvey
14
[Achselzucken] Wenn Sie kein Wörterbuch verwenden, um Ihre bereits vorhandenen Englischkenntnisse zu ergänzen , würde ich vorschlagen, dass Sie es falsch machen. Das Letzte, was ich vorschlagen würde, ist etwas, das unerfahrene Programmierer dazu veranlasst, nicht mehr als bisher am Wortschatz festzuhalten. Programmierer brauchen keine weiteren Wörter. Sie brauchen mehr Geschick.
Robert Harvey
13
@einpoklum, ein Glossar wird hier nicht weiterhelfen. Die Beschreibung des Wortes 'lvalue' ist wahrscheinlich entweder zu technisch für einen Anfänger oder in Anlehnung an 'das, was sich auf der linken Seite einer Aufgabe befinden kann', was ebenso wenig hilfreich ist.
Bart van Ingen Schenau
26

Eine relevante erwähnenswerte Technik ist die Verwendung eines zweiten Compilers. Clang hat zum Beispiel in bessere Fehlermeldungen investiert, aber jede andere Möglichkeit, den Fehler auszudrücken, kann aufschlussreich sein.

Dies gilt insbesondere für die komplexesten Arten von Fehlern. Wenn Sie beispielsweise zwei ähnliche Konstrukte mischen (was für Anfänger nicht ungewöhnlich ist), haben Compiler in der Regel Probleme, die richtige Fehlermeldung zu generieren. Dies kann zu Verwirrung führen, wenn der Compiler eine Fehlermeldung über die falsche Verwendung von Konstrukt A ausgibt, wenn Sie tatsächlich Konstrukt B beabsichtigt haben. Ein zweiter Compiler könnte darauf schließen, dass Sie B beabsichtigt haben.

MSalters
quelle
13

Jemand hat vor einiger Zeit einen Versuch unternommen, ein GCC-Fehlerglossar für Wikibooks zu erstellen , aber es sieht so aus, als wäre es nie ganz aufgegangen und wurde nicht aktualisiert.

Der Abschnitt "Fehler" ist viel weiter entfernt als der Abschnitt "Warnungen". Es sieht so aus, als wäre es an G ++ gerichtet, aber es gibt wahrscheinlich immer noch einige nützliche Informationen für Ihren Freund.

nBurn
quelle
12

Beachten Sie zusätzlich zu den obigen Antworten, dass die meisten Compiler keine umfassenden Fehlerglossare haben - dies wäre eine Menge Arbeit, da sich die Nachrichten selbst häufig ändern und es ziemlich viele von ihnen gibt.

Der beste Ersatz für ein Glossar ist der Zugang zum Internet. Wenn der Compiler einen Fehler ausgibt, den Sie nicht verstehen, gehen Sie davon aus, dass es sehr unwahrscheinlich ist, dass Sie der Erste sind, der auf ihn gestoßen ist und verwirrt wurde. Ein schnelles Auffinden der genauen Nachricht durch Google ist häufig ausreichend, um Ihnen viele Informationen in einem einfach zu lesenden Format zur Verfügung zu stellen, häufig mit einem Beispielcode, der Ihrem eigenen Code sehr ähnlich ist.

Darüber hinaus ist Zeit und Vertrautheit mit der Sprache und dem Compiler alles, was Sie brauchen. Das und der gute Rat von Karl Bielefeldt .

Dúthomhas
quelle
1
Ich denke nicht, dass es eine Menge Arbeit wäre, sie zu warten. Darüber hinaus kann es von der Öffentlichkeit hinzugefügt werden, z. B. in einem Stackoverflow oder einem Wiki, wobei vertrauenswürdige Personen über Editor-Berechtigungen verfügen.
Einpoklum
6
@einpoklum Hast du jemals die PHP-Dokumente gesehen? Das passiert, wenn die Community sich darum kümmert.
Kevin
4
Es war einmal, als einzige Ressource standen veröffentlichte (gedruckte) Handbücher zur Verfügung. Sie waren in der Regel gut genug geschrieben, um die erforderlichen Informationen / Anleitungen zur Lösung eines Problems bereitzustellen. Mit der Entwicklung des Internets veröffentlicht niemand mehr in gedruckter Form (wenn überhaupt, ist es online). Die Qualität von "offiziellem" Referenzmaterial (online oder anderweitig) ist in den Jahrzehnten, die ich programmiert habe, erheblich gesunken. Die beste verfügbare Ressource ist daher häufig Google, und die nützlichsten Ergebnisse tauchen häufig in Stackoverflow auf.
Zenilogix
2
Selbst wenn ein Glossar nicht vorhanden sind , können Suchmaschinen die beste Weg, um auf sie zuzugreifen. Sie sind auch nützlich, wenn Sie sich in einem unbekannten Gebiet befinden: wenn das einzige Suchergebnis der Quellcode ist, der die Fehlermeldung definiert;)
Warbo
2
Im College habe ich einmal den Compiler-Fehler "Dave glaubt nicht, dass dies passieren sollte. Bitte senden Sie ihm eine E-Mail an <[email protected]>". Ich habe ihm eine E-Mail geschickt und tatsächlich war ich der erste, der diesen Fehler entdeckt hat!
user1118321
6

Der C-Standard verwendet eine Reihe von Begriffen wie "lvalue" und "object" auf eine Weise, die sich von anderen Programmiersprachen unterscheidet, und Compilermeldungen werden häufig in diesen Begriffen geschrieben. Die Verwendung von Terminologie ist in einigen Teilen des Standards inkonsistent. Wer jedoch C erlernen möchte, sollte sich die Entwürfe der Standards C89, C99 und / oder C11 sowie die zugehörigen Begründungsdokumente ansehen. Die Suche nach beispielsweise "C99 Entwurf" oder "C89 Begründung" sollte ziemlich gut funktionieren, obwohl Sie möglicherweise sicherstellen müssen, dass Sie das erwartete Dokument erhalten. Obwohl die meisten Compiler den C99-Standard unterstützen, kann es nützlich sein, zu wissen, wie er sich vom C89-Standard unterscheidet, und die C89-Begründung bietet möglicherweise einen historischen Hintergrund, den spätere Versionen nicht bieten.

Superkatze
quelle
11
Der C-Standard ist ein sehr dichter und schwerer Text. Ein Anfänger hat keine Chance, es zu verstehen.
NieDzejkob
4
@NieDzejkob: Die von Compilern verwendete Terminologie - worum es bei der Frage zu gehen scheint - ist aus dem Standard abgeleitet. Sie haben zwar Recht, dass Teile des Standards unverständlich sind (zum Teil, weil er vom Komitee entworfen wurde und die Autoren offenbar nicht genau verstehen, was Teile davon bedeuten sollen), aber jeder, der verstehen möchte, was Begriffe wie "lvalue" sollten wissen, woher sie kommen. Außerdem, wenn man verstehen will, warum so etwas x=0x1e-xeinen Fehler ergibt, weiß ich wirklich nichts anderes als den Standard ...
Superkatze
3
Ich stimme @NieDzejkob zu: Der C-Standard ist nicht die Art von Text, mit der Sie einen Neuling konfrontieren möchten. Neulinge brauchen schnell positive praktische Erfahrungen . Und sie müssen nacheinander neue Dinge lernen, wenn sie auftauchen. Das Lesen eines Standards oder einer Begründung nimmt viel zu viel Zeit in Anspruch, während ein Neuling vollständig mit Informationen überladen wird.
cmaster
2
@cmaster: Ich habe vor langer Zeit mit dem C89 Standard angefangen und es war auch in den Tagen vor Browsern mit einer praktischen Funktion zum Suchen von Text nicht so schlimm. Ich gebe zu, dass spätere Standards immer schlechter geworden sind. Obwohl sich niemand auf den Standard als alleinige Referenz stützen sollte, ist es wichtig zu erkennen, dass das Verhalten von Mikrocomputer-Compilern und die Verhaltensweisen des Standards von schlechter Qualität unterschiedlich sind mit letzterem umzugehen.
Supercat
3
@cmaster: Auf jeden Fall sollte jemand, der C programmiert, den Standard kennen und wissen, wie man ihn bei Bedarf abruft, auch wenn er nicht versucht, das Ganze zu lesen. Wenn man beispielsweise eine Websuche nach einer Standardbibliotheksfunktion durchführt, kann man eine Referenz finden, die das Verhalten einer Implementierung in einigen Eckfällen beschreibt, ohne zu erwähnen, dass aus Sicht des Standards diese Eckfälle undefiniertes Verhalten und andere Implementierungen möglicherweise aufrufen nicht auf die gleiche Weise arbeiten. Wenn man stattdessen den Standard durchsucht, kann man dieses Problem vermeiden.
Supercat
5

Ich bin überrascht, dass niemand die offensichtliche Antwort gegeben hat und ich vermute, die in der Praxis am häufigsten verwendete: Lies einfach nicht die Fehlermeldungen.

Die überwiegende Mehrheit des Werts der meisten Fehlermeldungen besteht einfach darin, dass in dieser oder jener Zeile etwas nicht stimmt. Meistens schaue ich mir nur die Zeilennummer an und gehe zu dieser Zeile. Mein "Lesen" der Fehlermeldung zu diesem Zeitpunkt ist normalerweise genau das, was mein Auge im Vorbeigehen bemerkt, nicht einmal ein Überfliegen. Wenn nicht sofort klar ist, was an oder in der Nähe der Leitung nicht stimmt, lese ich die Nachricht tatsächlich. Dieser Workflow ist mit einer IDE oder einem Tool, das Fehler vor Ort hervorhebt, noch besser und befolgt automatisch den Vorschlag von Karl Bielefeldt, nur kleine Änderungen zu berücksichtigen.

Natürlich zeigen die Fehlermeldungen nicht immer auf die entsprechende Zeile, aber dann zeigen sie oft auch nicht auf die entsprechende Grundursache, sodass selbst ein umfassendes Verständnis der Fehlermeldung nur bedingt hilfreich ist. Es dauert nicht lange, um eine Vorstellung davon zu bekommen, welche Fehlermeldungen zuverlässiger sind, wenn es darum geht, die richtige Leitung zu finden.

Einerseits sind die meisten Fehler, die ein Anfänger wahrscheinlich macht , für einen erfahrenen Programmierer schmerzhaft offensichtlich, ohne dass die Hilfe des Compilers erforderlich ist. Auf der anderen Seite ist es weniger wahrscheinlich, dass sie für den Anfänger so offensichtlich sind (obwohl viele offensichtlich sind, sind die meisten Fehler dumme Fehler). An diesem Punkt stimme ich Robert Harvey voll und ganz zu, der Anfänger muss sich nur mit der Sprache vertraut machen. Daran führt kein Weg vorbei. Compiler-Fehler, die auf unbekannte Konzepte verweisen oder überraschend erscheinen, sollten als Aufforderung zur Vertiefung der Sprachkenntnisse angesehen werden. Ähnliches gilt für Fälle, in denen der Compiler sich beschwert, Sie jedoch nicht erkennen können, warum der Code falsch ist.

Auch hier stimme ich Robert Harvey zu, dass eine bessere Strategie zur Ausnutzung von Compilerfehlern erforderlich ist. Ich habe oben einige Aspekte umrissen, und die Antwort von Robert Harvey enthält andere Aspekte. Es ist nicht einmal klar, was Ihr Freund mit einem solchen "Glossar" zu tun hofft, und es ist sehr unwahrscheinlich, dass ein solches "Glossar" Ihrem Freund tatsächlich von großem Nutzen ist. Compilerbotschaften sind sicherlich nicht der Ort für eine Einführung in die Konzepte der Sprache 1 und ein "Glossar" ist dafür nicht viel besser geeignet. Selbst mit einer klaren Beschreibung der Bedeutung der Fehlermeldung erfahren Sie nicht, wie Sie das Problem beheben können .

1 Einige Sprachen wie Elm und Dhall (und wahrscheinlich Racket) sowie einige "Anfänger-orientierte" Implementierungen von Sprachen versuchen dies jedoch. In diesem Sinne ist der Rat von MSalters, eine andere Implementierung zu verwenden, direkt relevant. Ich persönlich finde solche Dinge nicht überzeugend und nicht ganz auf das richtige Problem ausgerichtet. Das soll nicht heißen, dass es keine Möglichkeiten gibt, bessere Fehlermeldungen zu erstellen, aber für mich dreht sich alles darum, die Überzeugungen des Compilers und die Grundlage dieser Überzeugungen klarer zu machen.

Derek Elkins
quelle
4

Wie sollte ein unerfahrener Programmierer die Herausforderung des Verstehens von Compilerfehlermeldungen angehen? Insbesondere mit der Kombination von C und GCC?

Bitten Sie Ihren Freund, Folgendes zu tun, wenn er auf einen Fehler stößt, den er nicht versteht:

  • Entfernen / kommentieren Sie den Code, der seit dem letzten erfolgreichen Build hinzugefügt wurde.
  • Setzen Sie kleine Teile davon zurück und kompilieren Sie
  • Wiederholen, bis der Fehler auftritt

Compiler-Fehler sagen Ihnen nur, was der Compiler über Ihren Code nicht versteht, und nicht, was daran falsch ist. Dieser Ansatz benötigt ungefähr die gleiche Zeit wie das Durchsuchen des Fehlers und das Lesen einiger Dokumente oder eines StackOverflow-Posts, bietet jedoch ein besseres Verständnis dafür, was Sie falsch machen.

Lassen Sie sie auch so oft kompilieren, bis sie anfangen, an Projekten zu arbeiten, deren Erstellung einige Minuten in Anspruch nimmt. Dabei hilft es, Fehler zu entdecken, bevor zu viel anderer Code hinzugefügt wird.

Schließlich fordern Sie sie auf, jeweils an einer Sache zu arbeiten, nicht in mehreren Dateien zu arbeiten, ohne dazwischen zu kompilieren, keine mehreren Abhängigkeiten gleichzeitig einzuführen usw.

Kevin
quelle
4

Eine andere Technik wäre, dass der Freund im Laufe der Zeit sein eigenes Glossar schreibt, wenn er auf verschiedene Fehlermeldungen stößt. Oft ist der beste Weg, etwas zu lernen, es zu lehren. Natürlich wird er es wahrscheinlich nicht mehr brauchen, wenn das Glossar fertig ist.

Meine persönliche Erfahrung mit GCC ist, dass sich jede Fehlermeldung auf eine "übliche" Reihe von Fehlern bezieht. Wenn GCC beispielsweise sagt, dass Sie das & vergessen haben, bedeutet dies normalerweise, dass ich Klammern vergessen habe. Welche Fehler mit welchen Fehlermeldungen verbunden sind, hängt natürlich vom Programmierer ab, ein weiterer guter Grund für den Freund, sein eigenes Glossar zu schreiben.

Owen
quelle
1
Dieses Dokument hat den enorm wichtigen Nebeneffekt, dass es online gestellt werden könnte (selbst wenn es nur 5 bis 10 Einträge enthält) und ein hervorragendes Unterscheidungsmerkmal bei der Bewerbung um ein Praktikum wäre.
Josh Rumbut