天天看点

c语言中setjmp与longjmp(4)

sigsetjmp() is similar to setjmp(). If savesigs is non-zero, the set of blocked signals is saved in env and will be restored if a siglongjmp() is later performed with this env.

Exception handling

在这种情况下使用时,主要用于以下几种情况:

* As the condition to an if, switch or iteration statement

* As above in conjunction with a single ! or comparison with an integer constant

* As a statement (with the return value unused)

过多的滥用可能会导致出现错误(cause undefined behaviour)。编译器和环境不会去在意是否使用了这些约定。

另一个例子如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <setjmp.h>

void first(void);

void second(void);

static jmp_buf exception_env;

static int exception_type;

int main() {

    volatile void *mem_buffer;

    mem_buffer = NULL;

    if (setjmp(exception_env)) {

        printf("first failed, exception type %d/n", exception_type);

    } else {

        printf("calling first/n");

        first();

        mem_buffer = malloc(300);

        printf(strcpy((char*) mem_buffer, "first succeeded!"));

    }

    if (mem_buffer)

        free((void*) mem_buffer);

    return 0;

}

void first(void) {

    jmp_buf my_env;

    printf("calling second/n");

    memcpy(my_env, exception_env, sizeof(jmp_buf));

    switch (setjmp(exception_env)) {

        case 3:

            printf("second failed with type 3 exception; remapping to type 1./n");

            exception_type = 1;

        default:

            memcpy(exception_env, my_env, sizeof(jmp_buf));

            longjmp(exception_env, exception_type);

        case 0:

            second();

            printf("second succeeded/n"); 

    }

    memcpy(exception_env, my_env, sizeof(jmp_buf));

}

void second(void) {

    printf("entering second/n" );

    exception_type = 3;

    longjmp(exception_env, exception_type);

    printf("leaving second/n");

}

具体详见wiki百科 http://en.wikipedia.org/wiki/Setjmp.h

继续阅读