Wie kann ich meine Fehlerprüfung und -behandlung verbessern?

13

In letzter Zeit hatte ich Mühe zu verstehen, wie viele Überprüfungen richtig sind und welche Methoden richtig sind.

Ich habe ein paar Fragen dazu:

Was ist der richtige Weg, um nach Fehlern zu suchen (fehlerhafte Eingaben, fehlerhafte Zustände usw.)? Ist es besser, explizit nach Fehlern zu suchen oder Funktionen wie Asserts zu verwenden, die aus Ihrem endgültigen Code heraus optimiert werden können? Ich habe das Bedürfnis, ein Programm mit viel zusätzlichem Code, der in den meisten Situationen sowieso nicht ausgeführt werden sollte, explizit auf Unordnung zu überprüfen - und ganz zu schweigen davon, dass die meisten Fehler mit einem Abbruch- / Beendigungsfehler enden. Warum eine Funktion mit expliziten Prüfungen überladen, nur um abzubrechen? Ich habe nach Behauptungen im Vergleich zur expliziten Überprüfung von Fehlern gesucht und wenig gefunden, um wirklich zu erklären, wann dies zu tun ist.

Die meisten sagen: "Verwenden Sie Asserts, um nach Logikfehlern zu suchen, und verwenden Sie explizite Prüfungen, um nach anderen Fehlern zu suchen." Dies scheint uns jedoch nicht sehr weit zu bringen. Würden wir sagen, dass dies machbar ist:

Malloc returning null, check explictly
API user inserting odd input for functions, use asserts

Würde mich das bei der Fehlerprüfung verbessern? Was kann ich sonst noch tun? Ich möchte mich wirklich verbessern und besseren, "professionellen" Code schreiben.

Anon
quelle
3
Gute Frage, aber ich denke, es ist besser für eine der Schwesterseiten (Programmierer?) Geeignet.
Danke, ich war mir nicht sicher. Ich dachte, da es ziemlich codebezogen war, wäre SO in Ordnung gewesen.
Anon
3
Die einfache Antwort lautet: "Aus diesem Grund wurden Ausnahmen erfunden. Holen Sie sich eine bessere Sprache."
DeadMG
1
@DeadMG: setjmp/ longjmpsind in C verfügbar, sodass Sie keine neue Sprache benötigen.
user786653
3
@DeadMG: Jemand, der die C-Fehlerprüfung nicht richtig durchführen kann, hat in der Hölle die Chance, dass die C ++ - Ausnahmebehandlung richtig
läuft

Antworten:

4

Der einfachste Weg für mich, den Unterschied zu erkennen, besteht darin, zu bestimmen, ob die Fehlerbedingung zur Kompilier- oder Laufzeit eingeführt wird. Wenn es sich bei dem Problem um einen Programmierer handelt, der die falsche Funktion verwendet, sollten Sie die Aufmerksamkeit auf das Problem lenken. Sobald das Update jedoch in den aufrufenden Code kompiliert wurde, müssen Sie sich keine Gedanken mehr darüber machen, ob das Problem auftritt. Probleme wie Speichermangel oder falsche Eingaben von Endbenutzern können beim Kompilieren nicht behoben werden.

Karl Bielefeldt
quelle
2

Überprüfen Sie zu jeder Zeit alles, was sich nach Ihrer letzten Überprüfung möglicherweise geändert hat und nicht zu 100% unter Ihrem Befehl steht. Und auch: Während der Entwicklung trauen Sie sich selbst nicht! ;-)

Okokok ... "irgendetwas" bedeutet, dass nach solchen Dingen gesucht wird, die einen abnormalen Abbruch verursachen , oder nach Dingen, die Ihre Anwendung / Ihr System dazu bringen könnten, Dinge zu tun, die es nicht tun sollte.

Im Ernst, der letzte Teil des letzten Satzes ist wichtig, weil er auf das Hauptproblem hinweist:

Wenn Sie wollen ein stabiles System das Hauptanliegen bauen es nicht darum , was das System tun sollte, sondern lassen es in der Lage sein , solche verbindliche Dinge zu tun, was man braucht kümmern , was es sollte nicht tun, auch wenn es „clutters Ihre Code".

alk
quelle
1
+1 für 'alles überprüfen'. Ich kaufe mir das Argument der Code-Unordnung nicht: Jeder Programmierer sollte sowieso in der Lage sein, zwischen Fehlerprüfung und tatsächlicher Logik zu unterscheiden.
27.
2

Der springende Punkt bei der Fehlerbehandlung ist nicht, ob und wie Sie das Problem beheben. Es ist mehr von dem, was Sie tun, nachdem Sie davon erfahren haben .

Zunächst einmal - ich würde sagen, es gibt keinen Grund, warum ein einzelner Fehler, der von einer untergeordneten Methode zurückgegeben wird, nicht behandelt werden sollte. Und Fehler und Ausnahmen sind nur mehr als die Rückgabewerte oder alle try / catch.

  1. Nur werfen und fangen ist nicht genug.
    Sehen Sie sich Folgendes an : Wenn der Autor erklärt, dass die Ausnahme möglicherweise unterdrückt wird, indem nur abgefangen wird, aber nichts unternommen wird, und wenn nicht genug getan wird, um den Schaden rückgängig zu machen, ist es schlimmer, als den Code einfach so laufen zu lassen. In ähnlicher Weise kann es hilfreich sein, die "log" -Anweisung zu schreiben, wenn eine Datei geöffnet oder ein Lesefehler aufgetreten ist, um den Grund zu finden - aber bis das Programm beendet wird, können die Daten beschädigt werden! Es ist nicht genug zu sagen, dass ich viele Versuch / Fang habe - es ist wichtiger zu wissen, was sie wirklich tun!

  2. Missbrauche den Versuch nicht zu fangen.
    Manchmal - meistens faule oder naive Programmierer - denken, dass ihre Arbeit vorbei und einfach ist, nachdem sie ausreichend try / catch geschrieben haben. Häufig ist es am besten, Korrekturmaßnahmen anzuwenden und den Vorgang fortzusetzen, anstatt nur das Ganze zu löschen. Wenn dies nicht möglich ist, muss entschieden werden, auf welcher Ebene Sie zurückkehren müssen. Versuchen Sie je nach Kontext und Schweregrad, die Verschachtelung von Fängen sorgfältig zu gestalten. Zum Beispiel - siehe dies und das

  3. Definieren Sie, wer verantwortlich ist:
    Als Erstes müssen Sie festlegen, ob die Eingabe für die Routine selbst nur ein inakzeptables (oder bislang nicht behandeltes) Szenario ist oder eine Ausnahme aufgrund von Umgebungsbedingungen (z. B. Systemproblemen, Speicherproblemen) darstellt Ist diese Situation ein völlig internes Ergebnis des Algorithmus? In allen Fällen - die Ebene, auf die Sie zurückkehren möchten, oder die Aktion, die Sie ausführen möchten, unterscheiden sich erheblich. In diesem Licht möchte ich sagen, dass es gut ist, abort () zum Beenden des Programms zu machen, wenn Sie den Code in der Produktion ausführen - aber nicht für jede Kleinigkeit. Wenn Sie eine Speicherbeschädigung oder einen Mangel an Speicher feststellen, ist es sicher, dass die Dinge auch dann sterben, wenn Sie Ihr Bestes geben. Aber wenn Sie einen Nullzeiger am Eingang erhalten - ich würde nicht

  4. Definieren Sie, was das bestmögliche Ergebnis ist:
    Was alles unter Ausnahmen getan werden muss, ist sehr kritisch. Wenn zum Beispiel in einem unserer Fälle ein Mediaplayer feststellt, dass er keine vollständigen Daten hat, die dem Benutzer wiedergegeben werden können, was sollte er dann tun?

    • Überspringen Sie entweder einen schlechten Teil und versuchen Sie, mit guten Dingen weiterzukommen.
    • Wenn dies zu viel passiert, überlegen Sie, ob Sie mit dem nächsten Song fortfahren können.
    • Wenn es feststellt, dass es keine Datei lesen kann, halten Sie an und zeigen Sie etwas an.
    • in der Zwischenzeit
    • unter welchem ​​zustand soll ein spieler POP-UP für den benutzer und
    • wann sollte es alleine weitermachen?
    • Sollte es "aufhören" Dinge zu fragen, geben Sie dem Benutzer eine Rückmeldung
    • oder sollte es in irgendeiner ecke unauffällige kleine fehlernotizen setzen?

    All dies ist subjektiv - und vielleicht gibt es mehr Möglichkeiten, mit Problemen umzugehen, als wir es trivial finden. All dies setzt voraus, dass die Ausnahmetiefe aufgebaut und verstanden wird, und dass es möglich sein sollte, verschiedene Szenarien zu entwickeln.

  5. Manchmal müssen wir auf Ausnahmen prüfen, bevor sie auftreten. Das häufigste Beispiel ist der Fehler der Division durch Null. Im Idealfall muss man das testen, bevor eine solche Ausnahme ausgelöst wird - und wenn dies der Fall ist, versuchen Sie, den am besten geeigneten Wert ungleich Null zu setzen und weiterzumachen, anstatt Selbstmord zu begehen!

  6. Aufräumen. Zumindest müssen Sie das tun! Wenn eine Funktion 3 Dateien öffnet und eine vierte nicht geöffnet werden kann, müssen die ersten 3 natürlich geschlossen werden. Es ist eine schlechte Idee, diesen Job an eine darüber liegende Ebene zu delegieren. Wenn Sie sich entscheiden, gehen Sie nicht ohne Speicher zu reinigen. Und das Wichtigste: Auch wenn Sie die Ausnahme überlebt haben, informieren Sie die höheren Ebenen darüber, dass die Dinge nicht den normalen Verlauf genommen haben.

Die Art und Weise, wie wir die (normale) Funktionalität der Software in Bezug auf verschiedene Hierarchien oder Ebenen oder Abstraktionen sehen, sowie die Art und Weise, in der wir Ausnahmen nach Schweregrad und Umfang ihrer Entstehung kategorisieren müssen und andere Teile des Systems beeinflussen - das definiert wie man mit so unterschiedlichen Ausnahmen bestmöglich umgeht.

Beste Referenz: Code Craft Kapitel 6 - zum Download verfügbar

Dipan Mehta
quelle
1

Das Überprüfen von Fehlern nur während Debug-Builds ist eine BAD IDEA (tm), die wiederverwendbare Variablen unter Release-Overlays auf dem Stapel kompiliert, Schutzseiten entfernt, zweifelhafte Tricks mit Berechnungen ausführt, schwere Arthritis durch vorberechnete Verschiebungen ersetzt und so weiter.

Verwenden Sie auch die Fehlerprüfung in Release. Sie können auf Folgendes zurückgreifen:

if(somethinghitthefan)
     abort();

Dies hat auch einen sehr guten Nebeneffekt, den Sie definitiv nicht ignorieren werden, sobald die Anwendung auf dem PC von betta testers abstürzt.

Ereignisanzeige und Protokolle sind völlig nutzlos im Vergleich zu abort(), wer überprüft sie überhaupt?

Coder
quelle
Exit / Abbruch == schlimmsten User Experience je: Die Anwendung verschwindet nur ohne warum zu sagen ..
stijn
@ stijn: abortbricht in den Debugger ein / erstellt einen Dump. exitist schlecht, ja. Obwohl ich __asm int 3am meisten bevorzuge .
Coder
das ist wahr, und in C / C ++ neige ich dazu, Asserts auch mit __asm ​​int 3 zu schreiben, aber niemals ohne zumindest eine Beschreibung des Warum und vorzugsweise auch Zeile und Datei. Dann kann zumindest der Kunde Auskunft darüber geben, was genau passiert ist.
28.
0

Sie können
Folgendes tun: 1.Lesen und assimilieren Sie viel Code online und sehen Sie, wie er ausgeführt wird.
2.Verwenden Sie einige Debugging-Tools, um Fehlerregionen zu
lokalisieren Syntaxfehler.
4. Einige schlimmere Fehler treten aufgrund von logischen Fehlern im Programm auf, die schwerer zu finden sind. Hierfür können Sie sie ausschreiben und finden oder für kompliziertere versuchen, mit Personen zu sprechen oder Ressourcen wie Stackoverflow , Wikipedia , Google zu verwenden, um Hilfe zu erhalten Menschen.

DCV
quelle