Exception Handling? Impossible!

richw at ada-uts.UUCP richw at ada-uts.UUCP
Tue Aug 13 05:03:00 AEST 1985


EXCEPTION HANDLING ??!?

The following includes "files" of macros and a simple modification
of the "exit" routine which allows one to do pseudo-exception-handling
in C.  An example of their use is provided in the "test.c" file.

There are problems with these macros (and the modified "exit"),
I admit.  The purpose of this note is to get feedback on possible
solutions to some of the problems.  I'd also like INTELLIGENT comments
about what's going on (please refrain from verborrhea like "How
could you name the macro 'except_when'?!  Name it 'if_exception'!" ).

Problems I can see right off:

1) The raise macro must still use a return statement (which is why
   I've provided raise_return, for those cases where garbage results
   are inappropriate).

2) Arbitrary statements may be executed between the call to the procedure
   that raised an exception and the handler.

3) Unhandled exceptions come to the attention of the user only when
   another "raise" is attempted or when the program terminates.

4) The raise macro includes a return statement since most exceptions
   (at least in programs that I write) are used to signal alternate
   termination conditions of a procedure.  This implies that "local"
   exceptions can't be raised (e.g. to jump out of nested loops).

5) An "exception" is simply a string.  It's "declaration" requires (?)
   some redundancy (i.e. the variable name and the string literal will
   usually look the same).


-- Rich Wagner

------------------------- test.c -------------------------------

#include "exceptions.h"
#include <stdio.h>

Exception overflow = "Overflow";

raiser(b)
int b;
{
	fprintf(stderr, "Raiser called with %d\n", b);
	if (b) raise(overflow);
	fprintf(stderr, "Leaving raiser\n\n");
}

main()
{
	raiser(0);
	    except_when(overflow)
		    fprintf(stderr, "Caught when it wasn't raised\n");
	    end_except;
	raiser(1);
	    except_when(overflow)
		    fprintf(stderr, "Caught\n");
	    end_except;
	raiser(0);
	raiser(1);
	raiser(1);
	fprintf(stderr, "Last line of main\n");
}

------------------------ test output ----------------------------

Raiser called with 0
Leaving raiser

Raiser called with 1
Caught
Raiser called with 0
Leaving raiser

Raiser called with 1
Raiser called with 1
Unhandled exception: Overflow

------------------------ exceptions.h ---------------------------

extern int _xxraised;
extern char *_xxexc;

#define raise(e) { if (_xxraised) exit(1);\
                   _xxexc = e; _xxraised = 1; return; }
#define raise_return(e,r) { if (_xxraised) exit(1);\
                            _xxexc = e; _xxraised = 1 ; return r; }

#define except_when(e) if (_xxraised) {\
			      if (_xxexc == (e)) { _xxraised = 0;

#define when(e) } else if (_xxexc == (e)) { _xxraised = 0;

#define end_except } else exit(1); }

typedef char *Exception;

------------------------ exceptions.c -----------------------------


#include <stdio.h>

int _xxraised = 0;
char *_xxexc;

exit(status)
int status;
{
	if (_xxraised) {
		fprintf(stderr, "Unhandled exception: %s\n", _xxexc);
                _xxexit(status ? status : 1);
        }
	_xxexit(status);

        /*  _xxexit is the old "exit" we all know and love, */
        /*  just renamed.                                   */
}



More information about the Comp.lang.c mailing list