Chitika

Monday, September 16, 2013

gnu c/gcc exception handling

man setjmp states:

"setjmp() and longjmp(3) are useful for dealing with errors and interrupts encountered in a low-level subroutine of a program. setjmp() saves the stack context/environment in env for later use by longjmp(3). The stack context will be invalidated if the function which called setjmp() returns."

man lngjmp states:

"longjmp() and setjmp(3) are useful for dealing with errors and interrupts encountered in a low-level subroutine of a program. longjmp() restores the environment saved by the last call of setjmp(3) with the corresponding env argument. After longjmp() is completed, program execution continues as if the corresponding call of setjmp(3) had just returned the value vallongjmp() cannot cause 0 to be returned. If longjmp() is invoked with a second argument of 0, 1 will be returned instead."

Example at wikipedia:

#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
 
enum { SOME_EXCEPTION = 1 } exception;
jmp_buf state;
 
int main(void)
{
  if(!setjmp(state))                      // try
  {
    if(/* something happened */)
    {
      exception = SOME_EXCEPTION;
      longjmp(state, 0);                  // throw SOME_EXCEPTION
    }
  } 
  else switch(exception)
  {             
    case SOME_EXCEPTION:                  // catch SOME_EXCEPTION
      puts("SOME_EXCEPTION caught");
      break;
    default:                              // catch ...
      puts("Some strange exception");
  }
  return EXIT_SUCCESS;
}


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

#define TRY do{ jmp_buf ex_buf__; if( !setjmp(ex_buf__) ){
#define CATCH } else {
#define ETRY } }while(0)
#define THROW longjmp(ex_buf__, 1)

int
main(int argc, char** argv)
{
   TRY
   {
      printf("In Try Statement\n");
      THROW;
      printf("I do not appear\n");
   }
   CATCH
   {
      printf("Got Exception!\n");
   }
   ETRY;

   return 0;
}


Advanced Try...Catch...Finally: (source: http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html)

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

#define TRY do{ jmp_buf ex_buf__; switch( setjmp(ex_buf__) ){ case 0: while(1){
#define CATCH(x) break; case x:
#define FINALLY break; } default:
#define ETRY } }while(0)
#define THROW(x) longjmp(ex_buf__, x)

#define FOO_EXCEPTION (1)
#define BAR_EXCEPTION (2)
#define BAZ_EXCEPTION (3)

int
main(int argc, char** argv)
{
   TRY
   {
      printf("In Try Statement\n");
      THROW( BAR_EXCEPTION );
      printf("I do not appear\n");
   }
   CATCH( FOO_EXCEPTION )
   {
      printf("Got Foo!\n");
   }
   CATCH( BAR_EXCEPTION )
   {
      printf("Got Bar!\n");
   }
   CATCH( BAZ_EXCEPTION )
   {
      printf("Got Baz!\n");
   }
   FINALLY
   {
      printf("...et in arcadia Ego\n");
   }
   ETRY;

   return 0;
}

No comments:

Post a Comment