Exceptions in glib



Hi!

I was discussing the problem of error handling in GTK with my
colleagues, and ended up suggesting the use of an exception
mechanism. 

Here's my first implementation of this, I would like to hear your
opinions on whether that's a good thing to do in GTK or not:

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <glib.h>

GQueue* exception_environment; /* should end up in a per-thread structure */

#define g_throw(x) longjmp(g_queue_peek_tail(exception_environment), (x))
#define g_try   \
{ \
  jmp_buf env; \
  gpointer exception; \
  \
  if((exception = setjmp(env)) == 0) {\
    g_queue_push_tail(exception_environment, env);

#define g_catch(x) \
    g_queue_pop_tail(exception_environment);\
  } else {\
    g_queue_pop_tail(exception_environment);\
    if(exception == (x)) {

#define g_endtry \
    } else { \
      g_throw(exception); \
    } \
  } \
}

#define g_unwind_protect   \
{ \
  jmp_buf env; \
  gpointer exception; \
  \
  if((exception = setjmp(env)) == 0) {\
    g_queue_push_tail(exception_environment, env);

#define g_cleanup \
  } \
  g_queue_pop_tail(exception_environment);

#define g_endprotect \
  if(exception) { \
    g_throw(exception); \
  } \
}


void foo(int blubb) {
  if(blubb)
    g_throw(23);
}

void bar(int blubb) {
  g_unwind_protect {
    foo(blubb);
  } g_cleanup {
    g_print("Cleaning up\n");
  } g_endprotect;
}


int main(int argc, char** argv) {
  exception_environment = g_queue_new();

  g_try {
    bar(0);
  } g_catch(23) {
    g_print("Exception caught!\n");
  } g_endtry;

  g_try {
    bar(1);
  } g_catch(23) {
    g_print("Exception caught!\n");
  } g_endtry;

  return 0;
}

In terms of http://www.gwydiondylan.org/drm/drm_53.htm, this exception
mechanism is name-based and exiting. By replacing the equality test in
the macro by a type check, one could also get a class-based exception
mechanism. A callback-based exception handling would also be possible,
by capturing the non-local exit in a closure, although I suspect the
syntax for that would be rather messy.

Andreas






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]