Nullen setzten
-
Wie kann ich erreichen das ein Teil der asserts in der Release Version aktiv bleiben.
Die throw catch lösung für das erste assert gefällt mir besser.
denn IMHO soll der Aufrufer richtige Werte übergeben (er soll sicherstellen, dass die Werte valid sind.
Hier halte ich es eher mit einem Spruch der HP-Measurement Division.
precise talking, forgiven listening
Selber Korrekte Daten erzeugen, aber mit dem DAU rechnen und falls möglich die SW dagegen sichern.
-
PAD schrieb:
Wie kann ich erreichen das ein Teil der asserts in der Release Version aktiv bleiben.
Garnicht.
Die throw catch lösung für das erste assert gefällt mir besser.
Wie gesagt, da sind beide Lösungen üblich. Je nachdem was einem besser liegt.
Selber Korrekte Daten erzeugen, aber mit dem DAU rechnen und falls möglich die SW dagegen sichern.
Ich teste halt nur in der Debug Version - danach bin ich mir sicher, dass ich keine falschen Daten mehr habe.
-
Ich glaub bei fast jedem größeres Projekt schreiben die Entwickler sich ihr eigenes assert.
-
schrieb:
Ich glaub bei fast jedem größeres Projekt schreiben die Entwickler sich ihr eigenes assert.
Ich wuerde sowieso Vorschlagen, dass sich jeder sein eigenes assert() schreibt.
-
PAD schrieb:
Wie kann ich erreichen das ein Teil der asserts in der Release Version aktiv bleiben.
das würde dann doch etwas peinlich sein, wenn der endbenutzer nach stundenlanger tipparbeit mit einer assertion und einem programmabruch abgefertigt werden würde
-
Ich wuerde sowieso Vorschlagen, dass sich jeder sein eigenes assert() schreibt.
Echt? Hast du dafür auch eine Begründung?
-
PAD logged out schrieb:
Ich wuerde sowieso Vorschlagen, dass sich jeder sein eigenes assert() schreibt.
Echt? Hast du dafür auch eine Begründung?
Ja, assert ist böse
-
Vielleicht sollte da noch der Hinweis rein, dass man _dieses_ Assert dann besser nicht in Destruktoren verwenden sollte. Hab ich zumindest beim flüchtigen Überfliegen nicht sehen können.
Zu dem Thema habe ich mir auch noch http://www.cuj.com/documents/s=8464/cujcexp0308alexandr/ gebookmarkt, aber bisher nicht gelesen
-
mist, wollte gerade so eine klasse für mich schreiben wie es Shade beschrieben hat und dann die schlechte Nachricht von operator void.
-
Nur zur Klarstellung
PAD logged out
Das bin ich nicht
-
[quote=SHADE]Ich teste halt nur in der Debug Version - danach bin ich mir sicher, dass ich keine falschen Daten mehr habe. [/quote]
Du Glücklicher, ich habs mit Geräten zu tun für die ich/wir auf ihre QualitätsPrüfProgramme schreiben. Diese haben auch digitale Kommunicationsschnittstellen und selbst DAU´s sind dagegen manchmal angenehme Zeitgenossen. Wenn einer der Prüflinge spinnt sind falsche Daten in Inhalt und Form eher die Regel als die Ausnahme.
-
operator void schrieb:
Vielleicht sollte da noch der Hinweis rein, dass man _dieses_ Assert dann besser nicht in Destruktoren verwenden sollte.
ein assert() in einem Destruktor?
Wieso sollte so etwas vorkommen, bzw. inwiefern sollte dies schlechter sein als ein normales assert()?Ich hatte noch nie ein assert() in einem Dtor, aber selbst wenn es auftreten sollte wäre es immer noch besser als ein assert() - denn bei meinem Assert() kann es zu Resourcenlöchern kommen, beim echten ássert() kommt es dazu.
Welche Lösung würdest du vorschlagen?
Im Prinzip bleibt einem nichts anderes übrig als eine Exception zu werfen.
-
imho ist das im prinzip dann sowieso schon egal. 2 ausnahmen.. da stinkt was
aber eventuell könnte man ein assert machen, das das programm nur abbricht, wenn uncaught_exception() false liefert
-
Was passiert denn, wenn eine Exception im Destruktor ausgelöst wird? Ist das dann undefiniertes Verhalten?
-
Noch eine Frage, Shade:
Warum hast du hier exp nochmal geklammert?
if(!(exp))
-
Shade Of Mine schrieb:
ein assert() in einem Destruktor?
Wieso sollte so etwas vorkommen, bzw. inwiefern sollte dies schlechter sein als ein normales assert()?Zum Beispiel habe ich eine Grafikengine und viele Texturen. Die Texturen müssen auf derselben Grafikengine erstellt und dann auch gelöscht werden. Eine Textur länger zu verwenden, als die Grafikengine existiert, ist illegal. Also überprüft der Dtor der Grafikengine, ob alle Texturen freigegeben sind - sind sie es nicht, hat entweder der Benutzer der Klassen (=ich) Mist bei der Resourcenfreigabe gemacht oder im Grafiksystem selbst ist ein Fehler. (Das ganze Texturmanagement ist intern auch nicht gerade einfach.) Viel mehr als terminate() bleibt einem da nicht mehr übrig: Wenn die Invarianten meiner Klassen nicht eingehalten sind, können sie eventuell nicht einmal freigegeben werden.
Das Problem mit Dtoren ist dann noch, dass werfende Dtoren allgemein für schlechten Stil gehalten und deshalb in den meisten Überlegungen ignoriert werden. Viel Code (auch der von wiederum anderen Dtoren) verlässt sich einfach darauf, dass Dtoren nie werfen. Die Möglichkeiten für Undefined Behaviour breiten sich damit immer weiter aus.
Da ist mir der der Standard-assert-Dialog lieber, der gleich Debugging anbietet, auch wenn man es ohne Debugger gestartet hat. Im schlimmsten Fall kosten mich die Leaks einen Reboot pro entdecktem Logikfehler, und die meisten Resourcen, die ich verwalte, sind nicht einmal so kritisch. Der Aspekt sieht aber natürlich bei jedem anders aus.
-
marco9 schrieb:
Was passiert denn, wenn eine Exception im Destruktor ausgelöst wird? Ist das dann undefiniertes Verhalten?
nein, aber wenn bereits eine exception im werfen ist, kann es probleme geben:
class Gefaehrlich { public: ~Gefaehrlich () { throw "blub"; } }; int main () { try { Gefaehrlich g; throw "Hello World!"; } catch (const char *c) { cout << c << '\n'; } }
kannst du mal ausprobieren. 2 exceptions gleichzeitig lassen std::terminate seine grausamen terminierungsanweisungen ausführen
absichern dagegen geht zb mitclass GefahrGebannt { public: ~GefahrGebannt () { if (!uncaught_exception()) throw "Neue Exception!"; } };
aber das ist ebenso für manche programmierer, die davon ausgehen, das destruktoren niemals ausnahmen werfen, gefährlich.
also lieber dtors nicht ausnahmen werfen lassen.zum thema resourcenfreigeben: man kann doch nicht im terminate_handler absicherungen unterbringen, oder? sinnvoll? lieber keine ausnahmen in dtoren?
-
@operator void:
Und inwiefern ist da das terminate() besser als mein Assert() ?Bitte vergiss nicht, dass man bei meinem Assert() dann den Fehler abfangen kann und eine schöne Fehlermeldung ausgeben (und danach erst beenden).
Wie davie ja schon erklärt hat kann es zu Problemen kommen wenn eine Exception einen Dtor verlässt. Aber bei einem terminate() wird garnichts zerstört.
Ich bevorzuge da lieber die Variante mit den wenigeren Ressourcenlöchern. Wenn jemand eine bessere Variante kennt -> nur her damit.
@marco9:
Der Operator ! hat eine sehr starke Bindung
Damit es da nicht zu Problemen kommt habe ich sicherheitshalber geklammert.@davie:
uncaught_exception() ist in der Theorie natürlich recht praktisch, aber in der Praktit liefert es bei fast allen Compilern immer false
-
hmm ich hab davon gehört und es mit dem gcc ausprobiert. da funktioniert es
aber ob es das wirklich wert ist?
-
Shade Of Mine schrieb:
@operator void:
Und inwiefern ist da das terminate() besser als mein Assert() ?Mir sind potenzielle Resourcenleaks lieber als ein Haufen undefiniertes (und dabei auch unüberschaubares) Verhalten. Und wie gesagt, assert() verwende ich, um grundlegende Invarianten sicherzustellen und dafür ist es imho auch sehr brauchbar. Wenn ein assert fehlschlägt, ist die Möglichkeit des sauberen Aufräumens nicht gegeben. An der Stelle, wo in meinem Beispiel die Grafikengine merkt, dass die Texturen nicht ordnungsgemäß freigegeben wurden, kann sie einfach nicht viel Sinnvolleres mehr tun als den Fehler so klar wie möglich auszugeben und auf die Behebung des Fehlers durch mich zu warten. (Natürlich könnte man da noch einen komplizierten Mechanismus drumrum bauen, aber man kann die Texturen auch einfach richtig freigeben
)