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 14:58

>>24
The guy who wrote the anti-Sepples faq is a flaming idiot. His only point is basically "IT COMPILES FASTER HURR", but if you don't use any template and shit, the difference is unsignificant. Especially in a small, one-man project.

Most of the "FQA" is just straw men and loaded words. Like he calls something a "fiasco" to give off the impression that a feature is widely considered a disaster, even when it's absolutely not the case. You should always be skeptical of critics too, not just of proponents. There's a reason C++ is used a lot, and it's not "C++ programmers are retards who can't do C".

It doesn't matter, by the way, if exceptions are slow (and they are). You're only supposed to use them in exceptional cases, usually when user intervention is needed. If you're writing a function where failure is expected to happen often, C++ gives you various ways to do it: return a boolean flag, or if you already return stuff you can return a pair<data,bool> and then do if(pair.second){normalcode;}else{errorhandling;}, which isn't an ugly hack, and is hardly longer than a try/catch. You could also take a flag by reference and make it false if your function fails. You could make a function object which handles its own errors, or sets a flag if it couldn't recover (so in your main code you could do if(networkSenderWhatever->Failed()){blabla;} )

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