技术库 > C++

C语言的异常机制--setjump()和longjump()实现

技术库:tec.5lulu.com

from:tec.5lulu.com

  goto语句可以用于同一个函数内异常处理,不幸的是,goto是本地的,它只能跳到所在函数内部的标号上。为了解决这个限制,C函数库提供了setjmp()和longjmp()函数,它们分别承担非局部标号和goto作用。头文件<setjmp.h>申明了这些函数及同时所需的jmp_buf数据类型。
    1.setjmp(jbuf)设置“jump”点,用正确的程序上下文填充jmp_buf对象jbuf。这个上下文包括程序存放位置、栈和框架指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值。
    2. 以后调用longjmp(jbuf,r)的效果就是一个非局部的goto或“长跳转”到由jbuf描述的上下文处(也就是到那原来设置jbuf的setjmp()处)。当作为长跳转的目标而被调用时,setjmp()返回r (或1,如果r设为0的话)。(setjmp()不能在这种情况时返回0,否则就和设置jump点的返回值冲突了)  
#include "apue.h"  
#include <setjmp.h>  
  
#define TOK_ADD    5  
  
jmp_buf jmpbuffer;  
  
int  
main(void)  
{  
     char    line[MAXLINE];  
  
     if (setjmp(jmpbuffer) != 0)  
         printf("error");  
     while (fgets(line, MAXLINE, stdin) != NULL)  
        do_line(line);  
     exit(0);  
}  
  
 ...  
  
void  
cmd_add(void)  
{  
    int     token;  
  
    token = get_token();  
    if (token < 0)    /* an error has occurred */  
        longjmp(jmpbuffer, 1);  
    /* rest of processing for this command */  
}  

setjump和longjump返回时对auto变量、register变量、volatile变量和静态变量的恢复情况示例。cc -O选项表示编译优化。
longjump返回时一般情况下不会恢复到setjump时的值,此种情况属于未定义。
如果你不想让anto变量的值回滚,需要加上volatile属性。 

#include "apue.h"  
#include <setjmp.h>  
  
static void f1(int, int, int, int);  
static void f2(void);  
  
static jmp_buf jmpbuffer;  
static int     globval;  
  
int  
main(void)  
{  
     int             autoval;  
     register int    regival;  
     volatile int    volaval;  
     static int      statval;  
  
     globval = 1; autoval = 2; regival = 3; volaval = 4; statval = 5;  
  
     if (setjmp(jmpbuffer) != 0) {  
         printf("after longjmp:n");  
         printf("globval = %d, autoval = %d, regival = %d,"  
             " volaval = %d, statval = %dn",  
             globval, autoval, regival, volaval, statval);  
         exit(0);  
     }  
  
     /* 
      * Change variables after setjmp, but before longjmp. 
      */  
     globval = 95; autoval = 96; regival = 97; volaval = 98;  
     statval = 99;  
  
     f1(autoval, regival, volaval, statval); /* never returns */  
     exit(0);  
}  
  
static void  
f1(int i, int j, int k, int l)  
{  
    printf("in f1():n");  
    printf("globval = %d, autoval = %d, regival = %d,"  
        " volaval = %d, statval = %dn", globval, i, j, k, l);  
    f2();  
}  
static void  
f2(void)  
{  
    longjmp(jmpbuffer, 1);  
}   

 
$ cc testjmp.c               compile without any optimization  
$ ./a.out  
in f1():  
globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99  
after longjmp:  
globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99  
$ cc -O testjmp.c            compile with full optimization  
$ ./a.out  
in f1():  
globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99  
after longjmp:  
globval = 95, autoval = 2, regival = 3, volaval = 98, statval = 99  

C语言的异常机制--setjump()和longjump()实现


标签: int本文链接 http://tec.5lulu.com/detail/108aan4wm11y48s0d.html

我来评分 :6.1
0

转载注明:转自5lulu技术库

本站遵循:署名-非商业性使用-禁止演绎 3.0 共享协议

www.5lulu.com