Next: , Previous: , Up: Top   [Contents][Index]


3 Brief introduction to non–local exits

Let’s recall briefly how the standard, C language, non–local exits mechanism works; for the full documentation refer to the C Library. (libc)Non-Local Exits.

To use setjmp() and longjmp() we write chunks of code like the following:

#define JMP_ERROR_CODE          1

jmp_buf  here;

if (setjmp(here))
  {
    handle_the_error();
  }
else
  {
    do_something();
    if (an_error_occurred()) {
      longjmp(here, JMP_ERROR_CODE);
    }
    do_something_else();
  }

this is what happens:

This mechanism allows us to separate the exception handling code from the main code. By using here as argument to nested function calls: we can perform non–local exits across functions; something that is not possible with goto statements.

As always, care must be taken when the body allocates asynchronous resources. For each resource: the exception handler must detect if the allocation took place and execute release code. For example:

jmp_buf         here;
volatile void * P = NULL;

if (setjmp(here))
  {
    if (P)
      free(P);
  }
else
  {
    ...
    P = malloc(4096);
    ...
  }

Let’s see some logic example; we will assume the following preamble:

#include <assert.h>
#include <stdlib.h>
#include <setjmp.h>

#define JUMP_TO_ERROR           2

In the following code no jump is performed; we just call setjmp() once and never call longjmp():

jmp_buf         L;
int             flag = 0, code;

code = setjmp(L);
if (code) {
  flag = 2;
} else {
  flag = 1;
}
assert(0 == code);
assert(1 == flag);

In the following code we perform a jump and handle the logic with an if statement:

jmp_buf         L;
int             flag = 0, code;

code = setjmp(L);
if (JUMP_TO_ERROR == code) {
  flag = 2;
} else {
  flag = 1;
  longjmp(L, JUMP_TO_ERROR);
}
assert(JUMP_TO_ERROR == code);
assert(2 == flag);

In the following code we perform a jump and handle the logic with a switch statement:

jmp_buf         L;
int             flag = 0, code;

code = setjmp(L);
switch (code) {
case JUMP_TO_ERROR:
  flag = 2;
  break;
default:
  flag = 1;
  longjmp(L, JUMP_TO_ERROR);
}
assert(JUMP_TO_ERROR == code);
assert(2 == flag);

Next: , Previous: , Up: Top   [Contents][Index]

This document describes version 0.9.0-devel.3 of CCExceptions.