c语言中setjmp与longjmp(4)

来源:互联网 发布:琅琊榜台湾知乎 编辑:程序博客网 时间:2024/05/19 22:47

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);
 
/* This program's output is:
 
calling first
calling second
entering second
second failed with type 3 exception; remapping to type 1.
first failed, exception type 1
 
*/
 
/* Use a file scoped static variable for the exception stack so we can access
 * it anywhere within this translation unit. */
static jmp_buf exception_env;
static int exception_type;
 
int main() {
    volatile void *mem_buffer;
 
    mem_buffer = NULL;
    if (setjmp(exception_env)) {
        /* if we get here there was an exception */
        printf("first failed, exception type %d/n", exception_type);
    } else {
        /* Run code that may signal failure via longjmp. */
        printf("calling first/n");
        first();
        mem_buffer = malloc(300); /* allocate a resource */
        printf(strcpy((char*) mem_buffer, "first succeeded!")); /* ... this will not happen */
    }
    if (mem_buffer)
        free((void*) mem_buffer); /* carefully deallocate resource */
    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:
            /* if we get here there was an exception. */
            printf("second failed with type 3 exception; remapping to type 1./n");
            exception_type = 1;
 
        default: /* fall through */
            memcpy(exception_env, my_env, sizeof(jmp_buf)); /* restore exception stack */
            longjmp(exception_env, exception_type); /* continue handling the exception */
 
        case 0:
            /* normal, desired operation */
            second();
            printf("second succeeded/n");  /* not reached */
    }
    memcpy(exception_env, my_env, sizeof(jmp_buf)); /* restore exception stack */
}
 
void second(void) {
    printf("entering second/n" ); /* reached */
    exception_type = 3;
    longjmp(exception_env, exception_type); /* declare that the program has failed */
    printf("leaving second/n"); /* not reached */
}

 

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

原创粉丝点击