Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Exceptions in C

Name: Anonymous 2008-06-14 8:02

i made an exception handling header for C and thought /prog/ could find a use for it, anyway, enjoy:
(simple usage below)

exception.h
/**
 * exception handling for ANSI C
 * \note NOT thread-safe \br
 * values of automatic variables are unspecified (look to longjmp(3) man page)
 */
#ifndef __EXCEPTION_H
#define __EXCEPTION_H

/// programmer can declare this to achive deeper recursion
#ifndef __EXMAXNEST
#       define __EXMAXNEST 16
#endif
/// simple stack for environment buffers used by setjmp()
jmp_buf  __exbuf[__EXMAXNEST];
/// simple stack for exit values of longjmp()
int      __exvalue[__EXMAXNEST];
/**
 * simple stack to check if current exception has been handled
 * (needed for upward propagation)
 */
char     __exhandled[__EXMAXNEST];
/// simple stack pointer
int      __exnest = 0;

/// try block
#define try      {                                                           \
                    if(__exnest >=  __EXMAXNEST) {                           \
                        fprintf(stderr, "%s:%i: Too deep try (...) catch "   \
                                "recursion. Aborting... \n", __FILE__,       \
                                __LINE__);                                   \
                        abort();                                             \
                    }                                                        \
                    __exhandled[__exnest] = 0;                               \
                    if ((__exvalue[__exnest] =                               \
                         setjmp(__exbuf[__exnest++])) == 0) {
/// catch block
#define catch(x)    } else if (__exvalue[__exnest-1] == (x) ) {              \
                        __exhandled[__exnest-1] = 1;                         \
                        --__exnest;
/**
 * finally block
 * \note must be always included, even if no code goes into finally block
 */
#define finally     } else {                                                 \
                        __exhandled[__exnest-1] = 0;                         \
                        --__exnest;                                          \
                    }
/// closing part for try block
#define end_try     if( __exhandled[__exnest] == 0)                          \
                        if (__exnest != 0) {                                 \
                            longjmp(__exbuf[__exnest-1],                     \
                                    __exvalue[__exnest]);                    \
                        } else {                                             \
                            fprintf(stderr, "%s:%i: Unhandled "              \
                                    "exception %i. Aborting...\n",           \
                                    __FILE__,  __LINE__,                     \
                                    __exvalue[__exnest]);                    \
                            abort();                                         \
                        }                                                    \
                }
/// throws exception given as a parameter
#define throw(x)    longjmp(__exbuf[__exnest-1], (x))
/**
 * makes current exception unhandled (it will be propagated upwards), useful
 * to just print debug mesages from local variables and continue
 * unvinding the stack
 * \note can be safely used only in catch() block
 */
#define unhandled   __exhandled[__exnest] = 0
/**
 * does basically the same thing as unhandled but can
 * change exception type, better that throw in catch() because it doesn't make
 * the finally block unexecuted
 * \note can be safely used only in catch() block
 */
#define rethrow(x)  __exhandled[__exnest] = 0;                               \
                    __exvalue[__exnest] = (x)

#else

extern jmp_buf  __exbuf[__EXMAXNEST];
extern int      __exvalue[__EXMAXNEST];
extern char     __exhandled[__EXMAXNEST];
extern int      __exnest;

#endif


usage:
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include "exception.h"

int func(int a)
{
        throw(1);
}

int main(int argc, char** argv)
{
        try
                func(2);
        catch(2)
                printf("exception catched\n");
        catch(1)
                printf("weird exception, make it unhandled\n");
                unhandled;
        finally
                printf("always executed\n");
        end_try

        exit(0);
}

Name: Anonymous 2008-06-14 19:34

>>29
That is fucking ugly. You'd have to check both return value and catch the possible exception always, otherwise, it crashes.

>>28
You've got a good point. Also, he admits in the linked post that he's a EXPERT SEPPLES TROLL. But I have been always avoiding sepples, and he's right in a few aspects. At least, when referring to the feature bloat. But trying to say that everything in the FAQ is wrong, that everything in the language is evil, is too much, and he clearly failed in that sense.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List