linux C下的setjmp与longjmp介绍

setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理。

先来看一下这两个函数的定义:

#include <setjmp.h>

int setjmp(jmp_buf envbuf);

若直接调用则返回0,若从longjmp调用返回则返回非0值

setjmp函数用缓冲区envbuf保存系统堆栈的内容,以便后续的longjmp函数使用。setjmp函数初次启用时返回0值。

void longjmp(jmp_buf envbuf, int val);

从不返回

longjmp函数中的参数envbuf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。longjmp函数本身是没有返回值的,它执行后跳转到保存envbuf参数的setjmp函数调用,并由setjmp函数调用返回,此时setjmp函数的返回值就是val。

上面的说明有点拗口,通俗的解释是:先调用setjmp,用变量envbuf记录当前的位置,然后调用longjmp,返回envbuf所记录的位置,并使setjmp的返回值为val。当时用longjmp时,envbuf的内容被销毁了。其实这里的“位置”一词真正的含义是栈定指针。

接着让我们看一个小例子:

#include <stdio.h> 
#include <setjmp.h>
jmp_buf buf;
banana(){ 
    printf("in banana() \n"); 
    longjmp(buf,1);
    printf("you'll never see this,because i longjmp'd");
}
void main() 
{ 
    if(setjmp(buf)) 
        printf("back in main\n"); 
    else{ 
        printf("first time through\n"); 
        banana(); 
    }
}

这段代码的打印结果是:

first time through
in banana()
back in main

仔细看一下应该更能体会这对函数的作用了吧。

setjmp/longjmp的最大用处是错误恢复,类似try ...catch...

他们的功能比goto强多了,goto只能在函数体内跳来跳去,而setjmp/longjmp可以在到过的所有位置间。

你可能感兴趣的:(linux C下的setjmp与longjmp介绍)