Fröhliches Coden!
„Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren.“ --Benjamin Franklin
"The problem with internet quotes is that you cant always depend on their accuracy" -Abraham Lincoln, 1864
Samstag, 31. Januar 2009
Schöner Coden mit C, C++, Java, etc
Guter Stil im Quellcode ist sehr wichig, damit Software möglichst bugfrei und wartbar ist. Es gibt einige Regeln, mit denen man den doppelten und/oder unleserlichen Code vermeiden kann und zugleich automatisch den Quellcode kommentiert.
Exceptions in c - wie bauen?
Weil mir in c das Fehlerhandling ein bischen auf die Nerven ging, hab ich beschlossen Exceptions einzubauen. Die Basis für die Exceptions bilden longjmp und setjmp.
Was die Exceptions können
- Sehr schnelles Behandeln einer Exception
- Verschiedene Typen von Exceptions
- (Noch) Keine Unterstützung für Threads :(
- Funktionen die keine Exceptions werfen können auch nicht aufgefangen werden
- Der Compiler prüft nicht, ob Exceptions abgefangen werden
- Grundkenntnisse in c und den Präprozessor sind verdammt wichtig
- TRY CATCH wird versteckt zu einer switch case Abfrage.
- THROW springt
#include <stdio.h> #include "exception.h" void function(int number) { if (number < 0) THROW; } int main(int argc, char **argv) { int number; TRY; scanf("%i", &number); function(number); CATCH; printf("Exception\n"); return 1; TRYEND; return 0; }Dieses Programm soll bei der Eingabe einer negativen Zahl Exception ausgeben und 1 zurückgeben. Bei einer positiven Zahl erfolgreich beenden. Dazu muss die exception.h implementiert werden:
#ifndef EXCEPTION_H #define EXCEPTION_H #include <setjmp.h> jmp_buf marker; #define TRY switch(setjmp(marker)) { \ case 0: #define CATCH break; \ default: #define TRYEND } #define THROW longjmp(marker, 1); #endif /* EXCEPTION_H */Was passiert hier genau? Um das zu erklären muss erst mal gezeigt werden, wie die c Datei mit aufgelösten Exception Macros auschaut:
#include <stdio.h> void function(int number) { if (number < 0) longjmp(marker, 1); } int main(int argc, char **argv) { int number; switch(setjmp(marker)) { case 0: scanf("%i", &number)); function(number); break; default: printf("Exception\n"); return 1; } return 0; }Das Makro setjmp setzt nicht nur ne Marke sondern gibt auch einen Wert zurück:
- 0 wenn nicht gesprungen wurde sondern die Stelle durch den normalen Programmfluss aufgerufen wurde
- ansonsten einen von setjmp mitgelieferten Wert. Im Beispiel oben ist es die 1.
#define THROW(exc) longjump(buffer, exc);Um die Exception abzufangen muss noch das Makro CATCHIF implementiert werden:
#define CATCH_IF(exc) break; \ case exc:Jetzt sollte auch folgender Code funktionieren:
#include <stdio.h> #include "exception.h" #define EXC_TOOSMALL 1 #define EXC_OMGOMGOMG 2 void function(int number) { if (number < -100) THROW(EXC_OMGOMGOMG); else if (number < 0) THROW(EXC_TOOSMALL); } int main(int argc, char **argv) { int number; TRY; scanf("%i", &number); function(number); CATCH_IF(EXC_TOOSMALL); printf("Too small\n"); return 1; CATCH; printf("Exception not handled\n"); return 2; TRYEND; } EXC_TOOSMALL wird behandelt, EXC_OMGOMGOMG jedoch nicht.Verschachtelung kommt ein anderes Mal. Hierzu wird dann ein Stack von marker verwendet. Fröhliches Coden!
Abonnieren
Posts (Atom)