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
Kommentare (Atom)