Frage

Assertion wird verwendet, um zu überprüfen, ob eine Bedingung erfüllt ist (Voraussetzung, Nachbedingung, Invarianten) und Hilfe Programmierer finden Bohrungen während der Phase debuggen.

Beispiel:

void f(int *p)
{
  assert(p);
  p->do();
}

Meine Frage ist, brauchen wir die Bedingung anzunehmen, kann nicht entsprechend im Release-Modus und behandeln den Fall erfüllt werden?

void f(int *p)
{
  assert(p);

  if (p)
  {
    p->do();
  }
}

Immerhin Behauptung bedeutet, dass die Bedingung testet sollte NIE falsch sein. Aber wenn, wenn wir es nicht kontrollieren und es fehlschlägt, Programm stürzt. Klingt wie ein Dilemma. Wie geht ihr damit?

War es hilfreich?

Lösung

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

Eine Behauptung Versagen Mittel aus der Programmierer einen grundlegenden Fehler in ihrem Verständnis, wie es ist möglich, dass der Programmablauf fortzufahren. Dies ist eine Entwicklungshilfe, kein Produktionsbeihilfe. In der Produktion könnte man behandeln Ausnahmen , da sie "vielleicht" auftreten, während Behauptungen sollten "nie" fehlschlagen.

Wenn Sie im Lager sind, die sagt: „Oh, aber was, wenn Behauptungen in der Produktion scheitern? Brauche ich sich zu fangen!“ dann sind Sie nicht den Punkt. Fragen Sie sich in einem solchen Fall, Warum sind Sie nicht nur werfen eine Ausnahme (oder auf andere Weise Umgang mit dem Fehler)?

Im Allgemeinen Assertion ist nicht nur eine Abkürzung für „wenn die Bedingung nicht erfüllt, throw exception“ (na ja, manchmal, die die operationale Semantik, aber es ist nicht die denotational Semantik). Vielmehr eine Behauptung Mittel, um die Anwendung andernfalls ist in ein Zustand, der Entwickler glaubt nicht, ist auch möglich . Wollen Sie wirklich den Code wollen weiterhin in einem solchen Fall die Ausführung? Klar (ich würde sagen), Nein .

Andere Tipps

Defensive Programmierung ist immer am besten. Sie sollten immer davon ausgehen, dass trotz aller Tests, Ihre Anwendung mit Bugs versenden. Als solches ist es in Ihrem besten Interesse NULL Kontrollen in Situationen hinzufügen, wo Sie eine NULL-Zeiger Ehrerbietung vermeiden können und einfach weitergehen.

Es gibt jedoch Situationen, in denen es einfach keine einfache Möglichkeit, einen Absturz, und in den Fällen zu vermeiden, wird die Assertion ist Ihre einzige Möglichkeit, das Problem während des Entwicklungszyklus zu erfassen.

Ein wichtiger Punkt aber - behauptet wird auch verwendet, oft große Probleme mit der Integrität Ihrer Daten zu erfassen. Wenn Sie weiter vorbei an denen behauptet, könnten Sie korrumpieren Daten riskieren. In diesen Fällen kann es besser sein, eher zum Absturz zu bringen, als Ihre Daten zu zerstören. (Offensichtlich jede Art von Crash-Handler, dass zumindest eine vernünftige UI mit einer Fehlerbeschreibung bringt vorzuziehen wäre).

Genau genommen der zweite Code hat Redundanz.

void f(int *p)
{
  assert(p);
  if (p)    // Beats the purpose of assertion
  {
    p->do();
  }
}

Assertion Mittel Fehler ist aufgetreten. Etwas, das unerwartete / unhandled ist. In obigem Code, entweder

1) Sie sind den Fall richtig Umgang mit dem p null ist. (Durch nicht p- Aufruf> do ()) - was angeblich die richtige / erwartete Sache zu tun. Doch dann ist die Behauptung ein Fehlalarm .

2) Auf der anderen Seite, wenn durch nicht Aufruf p> tun (), wird etwas schief gehen (vielleicht weiter im Code oder in der Ausgabe), dann ist die Behauptung richtig, aber es soll kein Punkt in Fortsetzung sowieso.

In dem obigen Code der Programmierer arbeitet extra hart Griff Fälle, die sowieso fehlerhaft sind.

sagte, dass einige Leute wie zu behandeln behauptet als etwas schief gegangen ist, aber mal sehen, ob wir noch eine korrekte Ausgabe erhalten . IMO, das ist schlecht Strategie und schafft Verwirrungen während Bugfixing.

Assertions debuggen Code, nicht Code. Verwenden Sie sie nicht zu fangen Eingabefehler.

sind Assertions zu fangen Bugs verwendet zu testen. Die Theorie ist, dass Sie gut genug getestet haben zu wissen, dass es funktioniert, wenn Sie es veröffentlicht haben.

Wenn es irgendeine Möglichkeit, dass die Bedingung im wirklichen Leben Betrieb entstehen können, verlassen sich nicht auf Behauptungen -. Verwendung Ausnahmen oder einem anderen Fehler Mechanismus

Asserts sind nützlich für das Debuggen, wie Sie erwähnt. Sie sollten nie in der Produktion Code machen (wie kompiliert, es ist in Ordnung, sie in #ifdefs natürlich zu wickeln)

Wenn Sie sich in ein Problem laufen, wo es außerhalb Ihrer Kontrolle ist, zu beheben, und Sie müssen den Scheck in Ihrem Produktionscode ich etwas tun würde, wie:

void f(int *p)
{

  if (!p)
  {
    do_error("FATAL, P is null.");
  }

  p->do();
}

Wo do_error ist eine Funktion, die einen Fehler und sauber Ausfahrten protokolliert.

ich sagen lassen sie in in einem Release-Build. Es ist verpflichtet, Fehler in jedem gebaut werden. Mit behauptet in Ihrem Produkt Mitteln, das Problem leicht mehr genau bestimmen können, wenn Sie ein Problem Bericht à uwer erhalten.

Do viel Aufwand nicht im Umgang mit den Ausnahmen stellen. Einfach stellen Sie sicher, können Sie halten, die vollständige Ausnahme, includigg stacktrace erhalten. Das gilt für einen Release-Build im Besonderen.

Da viele Menschen zu kommentieren Behauptungen im Release-Modus setzen:

In dem, was ich auf Arbeit, Effizienz sehr wichtig ist (manchmal, Ausführung auf großen Datenmengen nimmt Dutzende von Stunden bis wenigen Tagen komplett). Daher haben wir spezielle Makros, die nur im Debug-Code behaupten (laufen während QA usw.). Als Beispiel ist eine Assertion innerhalb einer for-Schleife auf jeden Fall ein Overhead und Sie können es in Freigabe-Code zu vermeiden. Nach allem, wenn alle iz gut behauptet angeblich nicht zum Scheitern verurteilt.

Ein Beispiel, in dem Freigabecode behauptet gut ist - wenn Logik nicht einen bestimmten Zweig des Code treffen überhaupt soll. In diesem Fall assert (0) ist in Ordnung [also jede Art von assert (0) immer in Freigabecode gelassen werden].

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top