Was ist die Strategie, wenn die Assertion fehlschlägt?

7

Assertion wird verwendet, um zu überprüfen, ob eine Bedingung erfüllt ist (Vorbedingung, Nachbedingung, Invarianten), und hilft Programmierern, während der Debugging-Phase Lücken zu finden.

Zum Beispiel

%Vor%

Meine Frage ist, müssen wir annehmen, dass die Bedingung im Freigabemodus nicht erfüllt werden konnte, und den Fall entsprechend behandeln?

%Vor%

Schließlich bedeutet Behauptung, dass die getestete Bedingung NIEMALS falsch sein sollte. Aber wenn wir es nicht überprüfen und es fehlschlägt, stürzt das Programm ab. Klingt wie ein Dilemma. Wie gehst du damit um?

    
Eric Z 29.10.2010, 05:55
quelle

8 Antworten

20

Wenn die Assertion fehlschlägt, sollte das Programm abstürzen .

Ein fehlgeschlagener Assertion bedeutet, dass der Programmierer einen grundlegenden Fehler in ihrem Verständnis gemacht hat, wie es möglich ist, dass der Programmablauf fortschreitet. Dies ist eine Entwicklungshilfe, keine Produktionsbeihilfe. In der Produktion könnte man Exceptions so behandeln, wie sie "vorkommen", während Assertions "nie" ausfallen sollten.

Wenn du im Lager bist, das sagt: "Oh, aber was, wenn Behauptungen in der Produktion scheitern? Ich muss sie fangen!" dann verpasst du den Punkt. Fragen Sie sich in einem solchen Fall, warum werfen Sie nicht einfach eine Ausnahme (oder behandeln Sie den Fehler anderweitig)?

Im Allgemeinen ist assert nicht nur eine Kurzform für "wenn Bedingung nicht erfüllt ist, Ausnahme auslösen" (naja, manchmal ist das die operative Semantik, aber es ist nicht das Denotational Semantik). Ein Versagen der Assertion bedeutet vielmehr, dass die Anwendung in einem Zustand ist, von dem der Entwickler nicht glaubt, dass es sogar möglich ist. Möchten Sie wirklich, dass der Code in einem solchen Fall weiter ausgeführt wird? Natürlich (würde ich sagen), Nein .

    
user359996 29.10.2010, 05:59
quelle
2

Defensive Programmierung ist immer am besten. Sie sollten immer davon ausgehen, dass Ihre Anwendung trotz aller Tests mit Bugs ausgeliefert wird. Daher ist es in Ihrem Interesse, NULL-Checks in Situationen hinzuzufügen, in denen Sie eine NULL-Pointer-Deference vermeiden und einfach weitergehen können.

Es gibt jedoch Situationen, in denen es einfach keinen einfachen Weg gibt, einen Absturz zu vermeiden, und in diesen Fällen ist die Bestätigung die einzige Möglichkeit, das Problem während Ihres Entwicklungszyklus zu erkennen.

Ein wichtiger Punkt jedoch - Behauptungen werden auch oft verwendet, um größere Probleme mit der Integrität Ihrer Daten zu erkennen. Wenn Sie diese Behauptungen fortsetzen, riskieren Sie möglicherweise, Daten zu korrumpieren. In diesen Fällen kann es besser sein, Ihre Daten zu löschen als zu zerstören. (Offensichtlich ist jeder Crash-Handler, der zumindest eine vernünftige Benutzeroberfläche mit einer Fehlerbeschreibung anzeigt, vorzuziehen.)

    
EboMike 29.10.2010 05:59
quelle
1

Streng genommen hat der zweite Code Redundanz.

%Vor%

Assertion bedeutet, dass ein Fehler aufgetreten ist. Etwas, das unerwartet / unbehandelt ist. Im obigen Code entweder

1) Sie behandeln den Fall richtig, in dem p null ist. (indem Sie nicht p- & gt; do () anrufen) - was angeblich die richtige / erwartete Sache ist. Die Assertion ist dann jedoch ein falscher Alarm .

2) Wenn andererseits p- & gt; do () nicht aufgerufen wird, wird etwas schiefgehen (vielleicht weiter im Code oder in der Ausgabe), dann ist die Behauptung richtig, aber es sollte keinen Sinn geben in Fortsetzung sowieso.

Im obigen Code arbeitet der Programmierer besonders hart, um Fälle zu behandeln, die sowieso fehlerhaft sind.

Das heißt, einige Leute behandeln gerne, dass etwas schiefgelaufen ist, aber sehen wir, ob wir immer noch korrekte Ergebnisse erhalten . IMO, das ist eine schlechte Strategie und schafft Verwirrung bei der Fehlerbehebung.

    
JP19 29.10.2010 07:47
quelle
0

Behauptungen sind Debugging-Code, nicht Betriebscode. Verwenden Sie sie nicht, um Eingabefehler zu erfassen.

    
Ignacio Vazquez-Abrams 29.10.2010 05:59
quelle
0

Behauptungen werden verwendet, um Fehler beim Testen aufzufangen. Die Theorie ist, dass Sie gut genug getestet haben, um zu wissen, dass es funktioniert, sobald Sie es veröffentlicht haben.

Wenn die Möglichkeit besteht, dass die Bedingung im realen Betrieb auftritt, verlassen Sie sich nicht auf Behauptungen - verwenden Sie Ausnahmen oder andere Fehlermechanismen.

    
Mark Ransom 29.10.2010 05:59
quelle
0

Asserts sind nützlich für das Debuggen, wie Sie erwähnt haben. Sie sollten niemals in Produktionscode (wie kompiliert, es ist in Ordnung, sie in #ifdefs natürlich zu verpacken)

Wenn Sie auf ein Problem stoßen, bei dem Sie keine Kontrolle mehr haben und Sie den Produktionscode überprüfen müssen, würde ich Folgendes tun:

%Vor%

Where do_error ist eine Funktion, die einen Fehler protokolliert und sauber beendet.

    
OmnipotentEntity 29.10.2010 05:59
quelle
0

Ich sage, lassen Sie sie in einem Release-Build. In jedem Build müssen Fehler enthalten sein. Wenn Sie in Ihrem Produkt behaupten, können Sie das Problem leichter lokalisieren, wenn Sie einen Problembericht von A uwer erhalten.

Machen Sie sich nicht viel Mühe mit den Ausnahmen. Stellen Sie einfach sicher, dass Sie die vollständige Ausnahme einschließlich StackTrace erhalten können. Dies gilt insbesondere für den Release-Build.

    
H. den Breejen 29.10.2010 06:01
quelle
0

Da sich viele Leute dazu äußern, Assertions im Freigabemodus zu setzen:

In meiner Arbeit ist Effizienz sehr wichtig (manchmal dauert die Ausführung großer Datensätze Dutzende von Stunden bis zu einigen Tagen). Daher haben wir spezielle Makros, die nur im Debug-Code (während der QA usw.) aktiviert werden. Zum Beispiel ist ein assert innerhalb einer for-Schleife definitiv ein Overhead und Sie möchten es möglicherweise in Release-Code vermeiden. Schließlich, wenn alles gut ist, sollen Behauptungen nicht versagen.

Ein Beispiel, bei dem Release-Code bestätigt, dass es gut ist, ist - wenn Logik nicht in der Lage ist, einen bestimmten Code-Zweig überhaupt zu treffen. In diesem Fall ist assert (0) in Ordnung [daher kann jede Art von assert (0) immer im Freigabecode gelassen werden].

    
JP19 29.10.2010 07:53
quelle

Tags und Links