C异常处理机制:setjmp和longjmp

原创 2011年09月01日 16:53:52

setjmp()和longjum()是通过操纵过程活动记录实现的。它是C语言所独有的。它们部分你不了C语言有限的转移能力。这个两个函数协同工作,如下所示:
    *setjmp(jmp_buf j)必须首先被调用。它表示“使用变量j记录现在的位置。函数返回零。”
    *longjmp(jmp_buf j,int i)可以接着被调用。它表示“回到j所记录的位置,让它看上去像是从原来的setjmp()函数返回一样。但是函数返回i,使代码知道它实际上是通过longjmp()返回的。“坳口不?
    *当使用longjmp()时,j的内容被销毁。
    setjmp保存了一份程序的计数器和当前的栈顶指针。如果喜欢也可以保存一些初始值。longjmp恢复这些值,有效的转移控制并把状态重置回保存状态的时候。这被称做“展开堆栈(unwinding stack)",因为你从堆栈中展开过程活动记录,直到取得保存在其中的值。尽管longjmp会导致转移,但它和goto又有不同,区别如下:
    *goto语句不能跳出C语言当前的函数(这也是“longjmp”取名的由来,它可以跳的很远,甚至可以跳到其他文件的函数中)。
    *用longjmp只能跳回到曾经到过的地方。在setjmp的地方仍留有一个过程活动记录。从这个角度讲,longjmp更像是“从何处阿里(come from)“而不是”往哪里去(go to)”。longjmp接受一个额外的整型参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上条语句执行后自然而然来的这里的。
    下面的代码显示了setjmp()和longjmp()一例。
     #include <stdio.h>
     #include <setjmp.h>
     jmp_buf buf;
 
     banana() {
         printf("%s","in banana() \n");
         longjmp(buf,1);
         printf("%s","you will never see this \n");
     }
 
     int main() {
         if(setjmp(buf)) {
             printf("%s","back in main\n");
         }
         else {
             printf("%s","first time throught\n");
             banana();
         }
     }
    输出结果如下:
    first time throught
    in banana()
    back in main
    需要注意的地方是:保证局部变量在longjmp过程中一直保持它的值的唯一可靠方法是把它声明为volatile(这使用于那些值在setjmp执行和longjmp返回之间会改变的变量)
    setjmp/longjmp最大的用途是错误恢复。只要还没有从函数中返回,一旦发现一个不可恢复的错误,可以把控制转移到主输入循环,并从那里重新开始。有些人使用setjmp/longjmp从一串无数的函数调用中立即返回。还有些人用它们防范潜在的危险代码。
    setjmp/longjmp在C++中演变为更普通的异常处理机制"catch"和"throw"。

C语言中利用setjmp和longjmp做异常处理

错误处理是任何语言都需要解决的问题,只有不能保证100%的正确运行,就需要有处理错误的机制。异常处理就是其中的一种错误处理方式。1 过程活动记录(Active Record)C语言中每当有一个函数调用...
  • smstong
  • smstong
  • 2016-02-24 14:55:46
  • 3091

C中setjmp和longjmp用法

C中提供了goto语法,可以通过goto跳转到函数体内部标记的某一行代码,但是却无法跳出函数之外的任意位置。 为了解决这个限制,C函数库提供了setjmp()和longjmp()函数,它们分别承担非局...
  • oktears
  • oktears
  • 2015-01-28 16:32:10
  • 1892

构建C协程之setjmp/long_jmp篇

原理简介 在标准C中的头文件中定义了一组函数 setjmp / long_jmp 用来实现“非本地跳转”的功能,利用 setjmp 可以保存当前执行线索状态,稍后通过 long_jmp 函数...
  • kobejayandy
  • kobejayandy
  • 2014-12-06 22:16:45
  • 6406

linux系统中的setjmp()和longjmp()函数

1. 作用: setjmp()和longjmp() 可以实现非局部控制转移即从一个函数到另外一个函数的跳转。 2. 函数原型: #include int setjmp(jmp_buf env); v...
  • c1194758555
  • c1194758555
  • 2016-10-10 18:26:59
  • 1656

c语言 setjmp和longjmp 实现协线程

非局部跳转语句---setjmp和longjmp函数。 非局部指的是,这不是由普通C语言goto,语句在一个函数内实施的跳转,而是在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。 #in...
  • CodySnow
  • CodySnow
  • 2016-01-25 17:40:07
  • 934

C语言之setjmp和longjmp详细剖析

我希望看这篇文章的你对C++的传统异常处理,即try...catch...throw有了解(不是Windows SEH),这样才能方便你最深入的理解这2个C语言的反人类函数。 当然如果不了解就先看下...
  • a1875566250
  • a1875566250
  • 2014-10-20 11:23:28
  • 2526

setjmp与longjmp原理分析

一、setjmp与longjmp的用法参考下面的文章         http://blog.csdn.net/chenyiming_1990/article/details/8683413 二、s...
  • stillvxx
  • stillvxx
  • 2014-01-08 11:43:44
  • 1796

setjmp, longjmp用法简介

setjmp和longjmp其实就是goto的升级版,goto只能在同一个函数中跳转,但是setjmp和longjmp可以实现在不同的函数之间跳转。 下面是一个简单的示例演示,代码+运行结果,几行注...
  • wzzfeitian
  • wzzfeitian
  • 2013-07-14 16:51:37
  • 2731

setjmp/longjmp非局部跳转函数分析

之前就一直好奇setjmp()/longjmp()函数是怎么实现非局部跳转的,心中猜测应该是通过保存调用setjmp()函数处的栈上下文(stack context),之后通过函数longjmp()来...
  • origin_lee
  • origin_lee
  • 2015-04-15 12:13:02
  • 889

setjmp和longjmp很难和C++相处

setjmp和longjmp很难和C++相处     C程序员唯有以setjmp和longjmp才能近似这样的行为。但是longjmp在C++中有一个严重的缺陷:当它调整栈的时候,无法调用局部对...
  • chenglinhust
  • chenglinhust
  • 2013-08-15 08:57:21
  • 1092
收藏助手
不良信息举报
您举报文章:C异常处理机制:setjmp和longjmp
举报原因:
原因补充:

(最多只允许输入30个字)