Strukturierte Fehlerbehandlung
-
Würde mich interessieren, ob schon mal jemand von euch mit Makros sowas wie try-catch zusammengefrickelt hat. Manchmal hätte ich sowas gerne. Gibts das schon?
-
Stichwort man: setjmp, man: longjmp. Shade Of Mine geht in seinem Artikel auch kurz drauf ein: http://www.c-plusplus.net/forum/viewtopic-var-t-is-219865.html
-
-
(Server hat Schlafkrankheit - delayed answer)
War beides interessant, danke!
Hab noch die halbe Nacht gefrickelt.
Wenn man einen Stack von jmp_buf einführt, kann man die try's auch verschachteln und aus catch/finally-Blöcken wegspringen.ETRY ist auch unnötig, wenn man FINALLY nicht optional macht; dann steht eben am Ende meistens FINALLY;.
Bei mir sieht das jetzt so aus:
#include "ctry.h" #define STRANGE_ERROR ERROR(0x01) #define FILE_OPEN_ERROR ERROR(0x02) /* wrap arroung fopen() to raise errors instead of using the return value for error indication */ FILE *fopen_err(char *fn, char *mode) { /* throw an error if file could not be openend */ if (!fn) raise (FILE_OPEN_ERROR); /* trow a strange error if something happens, just for testing */ if (!mode) raise (STRANGE_ERROR); /* everything ok */ return NULL; } int _cmain(int argc, char **argv) { FILE *fp; try { fp = fopen_err("eins", NULL); printf("File opened successfully.\n"); } except (error) /* error hat einen Typ, der im Header definiert wird, ist momentan int */ if (error == FILE_OPEN_ERROR) printf("Handled FILE_OPEN_ERROR.\n"); else { printf("Bad error caught and could not be handled.\n"); raise (error); } finally ; return 0; } int main(int argc, char **argv) { return try_context(argc, argv, _cmain); }
Endlich mal was vernünftiges gemacht. Ist standardkonform und kompiliert.
-
Vielleicht stelle ich mich zu blöd, aber wo ist da der Vorteil zu
f = fopen(...); if(f == NULL) { printf("Handled FILE_OPEN_ERROR.\n"); return wasauchimmer; }
???
-
supertux schrieb:
Vielleicht stelle ich mich zu blöd, aber wo ist da der Vorteil zu
f = fopen(...); if(f == NULL) { printf("Handled FILE_OPEN_ERROR.\n"); return wasauchimmer; }
???
<ironie>Es ist strukturiiiiiiiiihieeeeeeeert
Also wirklich, supertux, mit solchen Aussagen kannst du doch gleich nur noch im "Das-alte-Denken"-Thread antworten</ironie>PS: std::fstream wirft auch keine Exception, wenn die Datei nicht geöffnet werden kann... und das finde ich auch sinnvoll, weil es standardmäßig entweder geöffnet oder nicht-geöffnet geben kann bei einer. Bei DotNet o.ä. ist das schon was anderes - da gibt es mehr Informationen, z.B. Datei existiert nicht, oder ist gelockt, oder der Benutzer hat nicht die entsprechenden Rechte zum Lesen/Schreiben. Das alles lässt sich durch Exceptions schöner abfangen als durch das untersuchen von gesetzten Flags. Aber so High-Level ist ANSI-C nun mal nicht, und da ist der File-Descriptor entweder NULL oder !NULL. Struktur hin oder her. supertux, du stellst dich nicht zu blöd
-
supertux schrieb:
Vielleicht stelle ich mich zu blöd, aber wo ist da der Vorteil
einen richtigen vorteil hätte es z.b. wenn man den coder zwingen könnte, dass er auch tatsächlich eine fehlerbehandlung einbaut (wie's bei sogenannten 'checked exceptions' der fall ist).
so hat man sich einen alternativen ausführungspfad gebaut, den man auch aus tief verschachtelten funktionen betreten kann. das ist vielleicht auch ein kleiner vorteil.Xantus schrieb:
PS: std::fstream wirft auch keine Exception, wenn die Datei nicht geöffnet werden kann... und das finde ich auch sinnvoll, weil es standardmäßig entweder geöffnet oder nicht-geöffnet geben kann bei einer.
aber c++'s 'new' wirft eine, weil es so unglaublich viele stufen zwischen 'speicher verfügbar' und 'nicht verfügbar' gibt?
-
Xantus schrieb:
PS: std::fstream wirft auch keine Exception, wenn die Datei nicht geöffnet werden kann... und das finde ich auch sinnvoll, weil es standardmäßig entweder geöffnet oder nicht-geöffnet geben kann bei einer. Bei DotNet o.ä. ist das schon was anderes - da gibt es mehr Informationen, z.B. Datei existiert nicht, oder ist gelockt, oder der Benutzer hat nicht die entsprechenden Rechte zum Lesen/Schreiben. Das alles lässt sich durch Exceptions schöner abfangen als durch das untersuchen von gesetzten Flags. Aber so High-Level ist ANSI-C nun mal nicht, und da ist der File-Descriptor entweder NULL oder !NULL. Struktur hin oder her. supertux, du stellst dich nicht zu blöd
vielleicht liegt es daran, dass ich fast ausschließlich C (für eingebettete Systeme/steuerungs bibs) schreibe, dass ich mich mit der DotNet Ecke gar nicht auskenne und deswegen als diese "tolle" Sachen nicht kenne. Aber ich sehe da keinen Vorteil (zumindest bei diesem Bsp) ob ich die Fehler duchs Auslesen von einem Bit oder durch syntaktsichen try-catch Zucker behandle.
-
Aber ich sehe da keinen Vorteil (zumindest bei diesem Bsp) ob ich die Fehler duchs Auslesen von einem Bit oder durch syntaktsichen try-catch Zucker behandle.
Ja, richtig: beides geht.
Die Frage ist, was einfacher/eleganter/besser zu formulieren ist.
Das ist sehr oft Geschmacksache.
Mit oben skizzierten Makros könnte man ein goto so gut verstecken, daß es keiner
von denen sieht, die immer sagen: nimm lieber temporäre Bits, weil:Es ist strukturiiiiiiiiihieeeeeeeert
Mein Beispiel ist aber btw auch der Gipfel der Nutzlosigkeit.
Die Sache wird irgendwann fehlerfrei laufen, dann werd ich sie hier posten.
Mein Beitrag im Kampf gegen C++.
-
flamer schrieb:
Mein Beitrag im Kampf gegen C++.
soso, don-Q de la mancha der 79.te legt sich wieder mal mit windmühlen an. sowas ist doch unnötig, denn der grösste feind von c++ ist immer noch c++ selbst. ausserdem, windmühlen sind fast von allein ausgestorben.
-
Aber Ruhm und Ehre...!