Defensive Programmierung
-
@Bashar:
Das ist für mich wieder ein Regressionstest ... wir drehen uns im Kreis...
Compiler mit Regressionstest?!
Wäre aber mal eine Erfindung.
-
Mir scheint ich sollte mal in Erfahrung bringen was ein Regressionstest genau ist bevor ich hier weiterposte schönes Wochenende dann ...
-
Auch so...
Hellau!!
-
Original erstellt von Prof84:
Auch so...
Hellau!!*Arghh*
-
ich bin der meinung dass foo keine chanze hat irgendwas zu ändern. Wenn jetzt ein NULL Zeiger übergeben wird, was kann foo machen? Exception werfen, OK.
Aber bar() kann viel mehr machen. bar() weiss dass die Datei "baz" sich nicht öffnen hat lassen. Also sollte bar() vielleicht schaun ob genug rechte da sind oder so - zumindest kann bar() einen sinnvollen Fehler ausgeben.
Das Problem bei foo() ist nämlich: es hilft nichts wenn foo() meldet: "man hat mir einen ungültigen Pointer übergeben". Dann muss ich nämlich suchen WO foo() aufgerufen wurde. OK, das geht ja mit debuggern recht gut - allerdings was machen wir wenn der Fehler nicht reproduzierbar ist? Dann wissen wir nur, dass foo() uU mit einem 0-Zeiger aufgerufen werden kann - Notlösung (was leider bei uns dann gemacht wird):
if(!f) return;
aber ist das das wahre?
-
Original erstellt von Shade Of Mine:
**Exception werfen, OK.
**der sinnvollste ort wo sie gecatcht werden sollte wäre in bar, alles ander kommt ein assert ähnlich, was sonnst sollen die oben da machen wenn sie von irgend wo unten so eine exception bekommen?
Original erstellt von Shade Of Mine:
Notlösung (was leider bei uns dann gemacht wird):
if(!f) return;
aber ist das das wahre?ist das nicht auch ein fehler im weitern programm verlauf?
-
ich bin der meinung dass foo keine chanze hat irgendwas zu ändern. Wenn jetzt ein NULL Zeiger übergeben wird, was kann foo machen? Exception werfen, OK.
Naja, bei der defensiven Programmierung, wird foo wohl nie in die Situation kommen einen NULL Zeiger zu erhalten, deswegen ist ja defensive Programmierung quatsch.
Aber ich muss dir recht geben, Fehler fängt man am besten an der Stelle ab, an de man dem User eine Vernünftige Fehlermeldung geben kann und ihm danach ein stabiles System überlassen kann.
-
das Beispiel war wohl zu abstrakt, geb ich zu. foo müßte ein boolsches Ergebnis haben und bei Fehlern nach oben propagieren, wenn es keine Exception wirft. Das Problem ist, dass ich momentan mit C arbeite (Legacy-Code), also keine Exceptions zur Verfügung habe.
Unter Umständen kann sich das ändern, aber dazu muß ich mich erst durchringen.
-
man kann auch unter C Exceptions simulieren, ist zwar nicht so toll wie in C++, aber hier ist mal ein kleiner denkanstoß
#include <setjmp.h> #include <stdio.h> #include <stdlib.h> struct exception_t { int no; jmp_buf buf; }; struct exception_t NOMEMORY; void init_exceptions(void) { NOMEMORY.no=1; } inline void throw(struct exception_t exception) { longjmp(exception.buf,exception.no); } #define catch(exception,dofunc,doexception) \ { \ int ret=setjmp(exception.buf); \ if(ret==0) \ dofunc \ else if(ret==exception.no) \ doexception \ } void *mymalloc(size_t n) { void *ptr=malloc(n); if(!ptr) throw(NOMEMORY); return ptr; } void foo(void) { free(mymalloc(1000000000000000u)); } int main(void) { init_exceptions(); catch(NOMEMORY, { foo(); }, { fprintf(stderr,"nicht genug speicher!\n"); exit(1); }); return 0; }
-
das Stack-Unwindig von longjmp ist nicht ganz so toll, da es keine Destruktoren (die es in C ohnehin nicht gibt) aufruft, dh sobald ich Resourcen anfordere, die ich explizit freigeben muß, geht das in die Hose.
-
ja, dass ist natürlich ein Problem. Aber das kann einem in C++ auch passieren (was nicht heissen soll, dass die Methode jetzt gut ist mit longjmp ;))
-
ja theoretisch, aber das Verhältnis von dynamischen und automatischen Objekten ist in C++ ein ganz anderes als in C. In C passiert alles was über primitive Datentypen und Mini-structs hinausgeht dynamisch, während sowas in C++ in Klassen mit auto-Semantik verpackt ist. Nimm doch nur Stringhandling als Beispiel.
[ Dieser Beitrag wurde am 01.03.2003 um 16:51 Uhr von Bashar editiert. ]