assert unter c++ schlecht?
-
operator void schrieb:
[...] allerdings wird das spätestens dann unbequem, wenn man Ausnahmen regelmäßig wirft und fängt.
Wenn man regelmäßig Ausnahmen wirft und fängt hat man ohnehin ein exceptionally mieses Design und sollte sich zuerst einmal darum kümmern
-
Ich finde Assertions sehr wichtig.
Das Standard-Makro assert() allerdings verwende ich nie, eben weil das Programm unkontrolliert beendet wird. Und was nützt es mir in einem GUI-Programm, wenn eine Meldung nach STDOUT geschrieben wird?! Also habe ich ein eigenes Makro ASSERT(), das wie assert() funktioniert, aber eine Exception wirft, die als Text die fehlgeschlagene Bedingung, sowie Zeile und Datei des Fehlers enthält.
Stefan.
-
assert() ist nur zum Debuggen da
Für den Fall, dass mit assert() das Standard-Assert-Makro gemeint ist, könnt ihr den Rest des Beitrags ignorieren, denn das ist imo wirklich gerade mal zum Debuggen geeignet.
Ansonten bin ich aber anderer Meinung.
Natürlich sind assertions besonders wichtig in der Entwicklungsphase und natürlich ist es an zeit-kritischen Stellen schön zu wissen, dass Assertions bequem ausgeschaltet werden können, ich halte es aber eher mit den "Pragmatischen Programmern" und bin der Meinung, dass assertions auch in der Release-Version ihre Berechtigung haben.
Eine Assertion stellt explizit klar, dass etwas bestimmtes nicht passieren *darf*. Passiert es dennoch, hat man einen Bug. Und Bugs sollte man so früh und direkt wie möglich erkennen und dann beseitigen nicht "behandeln" wie etwa Exceptions.
Das gilt sowohl für den Test, als auch für die reale Anwendung.Ein assert nur in der Debug-Version geht davon aus, dass man beim Testen alle Fehler findet. Das ist aber wohl in den aller wenigstens Fällen so. Außerdem ist der Testbetrieb immer auch ein anderer als der spätere Realbetrieb.
Mit anderen Worten:
Turning off assertions when you deliver a program to production is like crossing a high wire without a net because you once made it accross in practice. There's a dramatic value, but it's hard to get life insurance.
(Andrew Hunt, Dave Thomas: "The Pragmatic Programmer" Seite 123)
Oder noch anders ausgedrückt. Normalerweise meint man mit Assertions "Assertions as contracts", man kann Assertions aber auch als Sicherungen ("Assertions as fuses") betrachten. Eine Sicherung verhindert weder das Auftreten eines Fehlers noch behandelt sie einen solchen. Sie gibt nur mit einem mehr oder weniger lauten Knall bekannt, dass und wo ein Fehler aufgetreten ist.
Und wer bitte baut ein System mit hübschen Sicherungen, nur um diese in der fertigen Version dann durch simple Drähte zu ersetzen?
-
Ich sehe das nicht ganz so, weil du ja die Moeglichkeit hast, wenn dir jemand einen Bug Report zu schickt, dass Verhalten mit der Debug Version durchzuspielen und siehst wo der Fehler liegt ohne den Performance Verlust in der Release Version. Natürlich sollte man Fehler, die leicht zur Laufzeit passieren abfangen (zB. Datei nicht gefunden oder Speicher nicht allokiert) aber andere Dinge nicht.
-
Ich sehe das nicht ganz so, weil du ja die Moeglichkeit hast, wenn dir jemand einen Bug Report zu schickt, dass Verhalten mit der Debug Version durchzuspielen
Schonmal ein MT-Programm geschrieben? Ein winziger Timing-Unterschied und schon hast du in der Release-Version ein anderes Verhalten als in der Debug-Version. Also einen Bug sollte man imo schon dort suchen, wo er aufgetreten ist. Und wo wir dabei sind. Eine ausgelöste Assertion ist in der Regel viel näher am Bug, als eine Beschreibung der Art "Das Programm ist abegrauscht. Ich habe da gedrückt, dann hier und dann vielleicht noch dort".
Natürlich sollte man Fehler, die leicht zur Laufzeit passieren abfangen (zB. Datei nicht gefunden oder Speicher nicht allokiert)
In einer Desktop-Anwendung sollten das beides Exceptions und nicht Assertions sein. Ich rede von richtigen Fehlern. Dinge die nicht passieren dürfen. Nicht Dinge die nicht auftreten sollten, in bestimmten Ausnhamefällen aber aufrtreten können und dann behandelt werden müssen (-> z.B. kein Speicher).
ohne den Performance Verlust in der Release Version
Solange es keinen Nachweis für ein Performance-Problem gibt, würde ich mir nicht den Kopf über den Performance-Verlust zerbrechen. Hat man den kritischen Pfad einer Anwendung gefunden, kann man *dort* ja diie Assertions ausmachen. Aber erstmal auf verdacht alle Assertions auszuschalten klingt für mich fatal nach "premature optimization".
-
da wir schon bei dem Thema sind:
na gibt es einen schönen Fallstrick im ASSERT.
z.b.ASSERT(iIdx++ > 0);
dieser Ausdruck wird um eins erhöht und dann auf größer 0 geprüft (sonst exception).
In der Debug Version funktioniert das prima,
aber in der Release sieht das so aus :()
ui - da ist nichts - iIdx verändert sich nicht!
Um den Ausdruck trotzdem auszuwerten sollte man deshalb VERIFY verwenden.
VERIFY(iIdx++ > 0);
in der Release Version wird dann auch iIdx++ ausgeführt.
Bei ASSERT hätte man sonst einen Seiteneffekt, von dem man garnichts wüsste.
Ganz besonders hat das Auswirkungen, wenn man im Ausdruck Funktionsaufrufe verwendet.
-
lol
-
@Dezipaitor: Hier geht es nicht um Seiteneffekte von Makros, sondern um Assertion.
Ich verwende normalerweise ein mehrstufiges Assertionsystem. Es gibt welche, die nur in meiner Version während der Entwicklung vorhanden sind, welche, die auch in der Testversion für die entsprechenden Tester sind und sehr wenige, die im Release bleiben.
-
@Helium
verwendest du eine Bibliothek fuer die Assertions oder was selbstgeschriebenes ?ich habe mir gerade log4cpp angeschaut und bin mir noch nicht ganz sicher ...
schreibt man sich zweckmaessigerweise selber noch ein paar Makros fuer die Nutzung der Bibo oder verwendet man die Objekte/Funktionen direkt ?
-
Naja, ich meinte schon das Standard-assert...das kann ich in Release-Versionen beim besten Willen nicht drin lassen. Ich verwende z.B. fleißig (praktisch überall) smart-ptr, die beim Dereferenzieren nochmal per RTTI gucken, ob der static_cast auch wirklich gültig ist, und lauter solche Sachen... Allgemein sollte man natürlich auch in der Release-Version alles überprüfen, wo das Überprüfen nicht weh tut