it-swarm.com.de

Anfänger, die frustriert sind, weil sie kein Glossar mit Compilerfehlern haben

Ein Freund meiner Familie bat mich um Hilfe, als er das Programmieren lernte (in der Sprache C). Während wir uns unterhielten, äußerte er sich frustriert darüber, dass es schwierig ist, 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 verstehen kann. Er fragte mich: "Wie kommt es, dass die Compiler-Dokumentation keine längeren Erklärungen der Fehlermeldungen enthält?" - 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 noch nicht gesehen hatte. Ich komme mit der Suche nach der Fehlermeldung in einer Suchmaschine zurecht, aber anscheinend funktioniert das nicht immer für ihn - zumal die Fehler, auf die er stößt, häufiger auftreten und in mehreren unterschiedlichen Fällen auftreten, die er in Bezug auf seine Probleme hat besitzen.

Wie sollte ein unerfahrener Programmierer die Herausforderung angehen, Compiler-Fehlermeldungen zu verstehen? Speziell mit der Kombination von C und GCC?

65
einpoklum

Einige nützliche Techniken:

  • Anschalten -Wall und -Werror. Es mag nicht intuitiv erscheinen, wenn Sie Probleme mit der Entschlüsselung von Fehlermeldungen haben, um sogar 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 dazu führen zu schwer verständlichen Fehlern.
  • Versuchen Sie einfach, den ersten Fehler in der Liste zu beheben. Oft setzen sich Fehler gegenseitig zusammen, was dazu führt, dass spätere Fehlermeldungen nicht wirklich tatsächliche Fehler sind. Korrigieren Sie eine und kompilieren Sie neu. Wenn Sie mehr Erfahrung sammeln, können Sie mehrere Fehlermeldungen besser beheben.
  • Verwenden Sie die neueste mögliche Compilerversion. C ist eine extrem stabile Sprache. Daher besteht ein großer Teil der Verbesserungen bei 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, vor dem Kompilieren eine Menge Code zu schreiben. Schreiben Sie den kürzestmöglichen Betrag, der noch kompiliert werden kann. Wenn Sie seit dem letzten sauberen Kompilieren nur eine Zeile geändert haben, ist es viel einfacher herauszufinden, welche Zeile das eigentliche Problem enthält.
  • Schreiben Sie Unit-Tests. Es macht Sie sicherer, Refactoring-Änderungen zu klären, wenn Sie Kompilierungsfehler beheben.
163
Karl Bielefeldt

Ihr Freund braucht kein Glossar. Ein Glossar hilft ihm nicht. Was er braucht, ist eine bessere Vorstellung davon, was zu tun ist, wenn Compilerfehler auftreten.

C-Compilerfehler sind nicht so intuitiv wie beispielsweise C # -Compilerfehler, und zwar aus vielen Gründen, die hauptsächlich mit der "nah am Metall" -Natur von C zu tun haben. Das Lösen von Compilerfehlern in C ist keine Mustervergleichsübung, da der Fehler bei Ihnen liegt Empfangen hat möglicherweise nichts mit dem eigentlichen Problem zu tun. Im Gegensatz zu C # oder Java, wo eine Fehlermeldung normalerweise einem genauen Codeort und -problem zugeordnet ist, sind Fehler in C wahrscheinlich zahlreich und weit entfernt.

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

Die Strategie Ihres Freundes sollte nicht darin bestehen, dieses 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 tatsächliche Problem ist.

56
Robert Harvey

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

Dies gilt insbesondere für die komplexesten Fehlertypen. Wenn Sie beispielsweise zwei ähnliche Konstrukte verwechseln (was für Anfänger nicht ungewöhnlich ist), haben Compiler normalerweise ein Problem beim Generieren der richtigen Fehlermeldung. Dies kann zu Verwirrung führen, wenn der Compiler eine Fehlermeldung über die falsche Verwendung von Konstrukt A gibt, wenn Sie Konstrukt B tatsächlich beabsichtigt haben. Ein zweiter Compiler kann daraus schließen, dass Sie B beabsichtigt haben.

26
MSalters

Jemand hat vor einiger Zeit versucht, ein GCC-Fehlerglossar in Wikibooks , 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 ob es auf G ++ ausgerichtet war, aber es gibt wahrscheinlich noch einige nützliche Informationen für Ihren Freund.

13
nBurn

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

Der beste Ersatz für ein Glossar ist der Zugang zum Internet. Wenn der Compiler einen Fehler erzeugt, den Sie nicht verstehen, trösten Sie sich, dass es höchst unwahrscheinlich ist, dass Sie als erster auf ihn gestoßen sind und verwirrt wurden. Ein schnelles Google der genauen Nachricht reicht oft aus, um Ihnen viele Informationen in einfach zu lesendem Format zu liefern, oft mit Beispielcode, der Ihrem eigenen 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 .

12
Dúthomhas

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 solchen Begriffen geschrieben. Die Verwendung von Terminologie ist in einigen Teilen des Standards inkonsistent, aber jeder, der C lernen möchte, sollte sich Entwürfe der Standards C89, C99 und/oder C11 sowie die Begründungsdokumente dafür ansehen. Suchen nach z.B. "C99-Entwurf" oder "C89-Begründung" sollten ziemlich gut funktionieren, obwohl Sie möglicherweise sicherstellen müssen, dass Sie das Dokument erhalten, das Sie erwarten. Obwohl die meisten Compiler den C99-Standard unterstützen, kann es hilfreich 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.

6
supercat

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

Die überwiegende Mehrheit des Wertes der meisten Fehlermeldungen besteht einfach darin, dass in dieser und jener Zeile etwas nicht stimmt. Meistens schaue ich mir nur die Zeilennummer an und gehe zu dieser Zeile. Mein "Lesen" der Fehlermeldung an diesem Punkt ist normalerweise genau das, was mir im Vorbeigehen auffällt, nicht einmal ein Überfliegen. Wenn nicht sofort klar ist, was in oder in der Nähe der Leitung falsch ist, lese ich die Nachricht tatsächlich. Dieser Workflow ist sogar noch besser mit einem IDE oder Tooling, das Fehler vor Ort hervorhebt und automatisch Karl Bielefeldts Vorschlag ausführt, 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 begrenzt hilfreich ist. Es dauert nicht lange, um eine Vorstellung davon zu bekommen, welche Fehlermeldungen beim Auffinden der richtigen Leitung zuverlässiger sind.

Einerseits sind die meisten Fehler, die ein Anfänger wahrscheinlich macht, für einen erfahrenen Programmierer schmerzhaft offensichtlich, ohne dass der Compiler Hilfe benötigt. Andererseits ist es für Anfänger viel weniger wahrscheinlich, dass sie so offensichtlich sind (obwohl viele offensichtlich sind, sind die meisten Fehler dumme Fehler). An dieser Stelle stimme ich Robert Harvey voll und ganz zu, der Anfänger muss sich lediglich mit der Sprache vertraut machen. Daran führt kein Weg vorbei. Compilerfehler, 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 sich der Compiler beschwert, Sie jedoch nicht erkennen können, warum der Code falsch ist.

Auch hier stimme ich Robert Harvey zu, dass eine bessere Strategie zur Verwendung von Compilerfehlern erforderlich ist. Ich habe oben einige Aspekte skizziert und Robert Harveys Antwort gibt andere Aspekte. Es ist nicht einmal klar, was Ihr Freund mit einem solchen "Glossar" anfangen möchte, und es ist sehr unwahrscheinlich, dass ein solches "Glossar" Ihrem Freund tatsächlich von großem Nutzen ist. Compiler-Nachrichten sind sicherlich nicht der Ort für eine Einführung in die Konzepte der Sprache1 und ein "Glossar" ist nicht viel besser dafür. Selbst mit einer klaren Beschreibung der Bedeutung der Fehlermeldung erfahren Sie nicht, wie Sie das Problem beheben .

1 Einige Sprachen wie Elm und Dhall (und wahrscheinlich Racket) sowie einige "anfängerorientierte" 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. Dies bedeutet nicht, dass es keine Möglichkeiten gibt, bessere Fehlermeldungen zu erstellen, aber für mich geht es in der Regel darum, die Überzeugungen des Compilers und die Grundlage dieser Überzeugungen klarer zu machen.

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 zum Zeitpunkt der Fertigstellung des Glossars wahrscheinlich nicht mehr brauchen.

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 welchen Fehlermeldungen entsprechen, hängt natürlich vom Programmierer ab. Ein weiterer guter Grund für den Freund, sein eigenes Glossar zu schreiben.

4
Owen

Wie sollte ein unerfahrener Programmierer die Herausforderung angehen, Compiler-Fehlermeldungen zu verstehen? Speziell mit der Kombination von C und GCC?

Sagen Sie Ihrem Freund Folgendes, 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.
  • Legen Sie kleine Teile davon zurück und kompilieren Sie
  • Wiederholen, bis der Fehler auftritt

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

Lassen Sie sie auch häufig kompilieren, bis sie anfangen, an Projekten zu arbeiten, deren Erstellung Minuten dauert. Das Erkennen von Fehlern, bevor zu viel anderer Code hinzugefügt wird, hilft sehr.

Sagen Sie ihnen schließlich, sie sollen jeweils an einer Sache arbeiten, nicht in mehreren Dateien arbeiten, ohne dazwischen zu kompilieren, nicht mehrere Abhängigkeiten gleichzeitig einführen usw.

4
Kevin