精华内容
下载资源
问答
  • C语言异常处理机制--setjmp返回值

    千次阅读 2010-03-03 10:44:00
    使用setjmp时必须使用头文件setjmp.h。#include "setjmp.h"jmp_buf jmpbuffer; int setjmp(jmp_buf jmpbuffer); void longjmp(jmp_buf jumpbuffer, int retval); 其中 jmpbuffer 是相关的程序栈的环境上下文。 初始...

    使用setjmp时必须使用头文件setjmp.h。

    #include "setjmp.h"

    jmp_buf jmpbuffer;
     
    int setjmp(jmp_buf jmpbuffer);
    void longjmp(jmp_buf jumpbuffer, int retval);
     
    其中 jmpbuffer 是相关的程序栈的环境上下文。
    初始化jmpbuffer之后, setjmp第一次调用的时候会返回 0。
    longjmp跳转到setjmp处,其中第二个参数retval就是传递给setjmp, 作为setjmp的返回值。但是需要主要的是,如果retval设置为0, 即这样调用的时候 longjmp(jumpbuffer, 0), setjmp会返回1。

     

    例子如下:

    函数setjmp()的行为很特别,如果直接调用它,它便将所有与当前处理器相关的状态信息(比如指令指针的内容,栈指针等)保存到jmp_buf中并返回0。在这种情况下,它的表现与一个普通的函数一样。然而,如果使用同一个jmp_buf调用longjmp(),则函数返回时就好像刚从setjmp()中返回时一样-----又回到刚刚从setjmp()返回的地方。这一次,返回值是调用longjmp()时所使用的第二个参数,因此可通过这个值判断程序是从longjmp()返回的。

    展开全文
  • setjmp 与 longjmp解析

    2015-06-01 16:14:06
    setjmp 与 longjmp 提供了C语言中跳转的功能 以下是函数原型 int setjmp(jmp_buf env) void longjmp(jmp_buf env, int value) ...如果是从setjmp直接调用返回,setjmp返回值为0。如果是从longjmp恢复的

    setjmp 与 longjmp 提供了C语言中跳转的功能 以下是函数原型

    int setjmp(jmp_buf env)

    void longjmp(jmp_buf env, int value)

    setjmp env 用来建立本地缓冲区并且初始化,用于将来跳转回此处。env将被longjmp使用。如果是从setjmp直接调用返回,setjmp返回值为0。如果是从longjmp恢复的程序调用环境返回,setjmp返回非零值。

    longjmp 恢复env所指的缓冲区中的程序调用环境上下文,env所指缓冲区的内容是由setjmp子程序调用所保存。value的值从longjmp传递给setjmplongjmp完成后,程序从对应的setjmp调用处继续执行,如同setjmp调用刚刚完成。如果value传递给longjmp零值,setjmp的返回值为1;否则,setjmp的返回值为value

    #include <stdio.h>
    #include <setjmp.h>
    jmp_buf buf;
    void test_set_jmp(){
        printf("Now enter test_set_jmp()\n");
        longjmp(buf,1);
        printf("you'll never see this, because longjmp has jump to another");
    }
    int main(int argc, char *argv)
    {
        if(setjmp(buf))
            printf("Now I am back into main\n");
        else{
            printf("Now Im here, first time  in main()\n");
            test_set_jmp();
        }
        return 0;
    }
    

    输出结果:

    ivanx@ivanx-V:~/test$ ./a.out 
    Now Im here, first time  in main()
    Now enter test_set_jmp()
    Now I am back into main

    可以看出,第一次记录了跳转位置,这样 test_set_jmp 中调用了 longjmp,函数末尾的打印不会被执行。



    展开全文
  • setjmp和longjmp使用案例

    2019-10-29 12:29:45
    #include <stdio.h> #include <setjmp.h> static jmp_buf buf; void second(void) { printf("second\n"); // 打印 longjmp(buf,1); // 跳回setjmp的调用处 - 使得setjmp返回值为1 } v...
    #include <stdio.h>
    #include <setjmp.h>
    
    static jmp_buf buf;
    
    void second(void) {
        printf("second\n");         // 打印
        longjmp(buf,1);             // 跳回setjmp的调用处 - 使得setjmp返回值为1
    }
    
    void first(void) {
        second();
        printf("first\n");          // 不可能执行到此行
    }
    
    int main() {
        int res;
        int count=0;
        while(1){
            res = setjmp(buf);
            count++;
            printf("res:%d\n",res);
    
            if(count == 8)
            {
                break;
            }
        }
    
        if (!(res)) {
            first();                // 进入此行前,setjmp返回0
        } else {                    // 当longjmp跳转回,setjmp返回1,因此进入此行
            printf("main\n");       // 打印
        }
    
        return 0;
    }
    展开全文
  • setjmp 和 longjmp 函数

    2011-08-08 23:51:46
    成员函数 int setjmp(jmp_buf env) 创建本地的jmp_buf缓冲区并且初始化,用于将来跳转回此处。这个子程序[1] 保存程序的调用环境于env参数所指的缓冲区,env将被...如果是从setjmp直接调用返回,setjmp返回值
    •  成员函数
    int setjmp(jmp_buf env)创建本地的jmp_buf缓冲区并且初始化,用于将来跳转回此处。这个子程序[1] 保存程序的调用环境于env参数所指的缓冲区,env将被longjmp使用。如果是从setjmp直接调用返回,setjmp返回值为0。如果是从longjmp恢复的程序调用环境返回,setjmp返回非零值。
    void longjmp(jmp_buf env, int value)恢复env所指的缓冲区中的程序调用环境上下文,env所指缓冲区的内容是由setjmp子程序[1]调用所保存。value的值从longjmp传递给setjmplongjmp完成后,程序从对应的setjmp调用处继续执行,如同setjmp调用刚刚完成。如果value传递给longjmp零值,setjmp的返回值为1;否则,setjmp的返回值为value

    setjmp保存当前的环境(即程序的状态)到平台相关的一个数据结构 (jmp_buf),该数据结构在随后程序执行的某一点可被longjmp用于恢复程序的状态到setjmp调用所保存到jmp_buf时的原样。这一过程可以认为是"跳转"回setjmp所保存的程序执行状态。setjmp的返回值指出控制是正常到达该点还是通过调用longjmp恢复到该点。因此有编程的惯用法:if( setjmp(x) ){/* handle longjmp(x) */}

     

    • 成员类型

    jmp_buf

    数组类型,例如struct int[16][2]struct __jmp_buf_tag[3],用于保存恢复调用环境所需的信息。

     

    • 告诫与限制

    longjmp实现了非本地跳转,微软的IA32程序设计环境中正常的"栈卷回"("stack unwinding")因而没有发生,所以诸如栈中已定义的局部变量的析构函数的调用(用于销毁该局部变量)都没有执行。所有依赖于栈卷回调用析构函数所做的扫尾工作,如关闭文件、释放堆内存块等都没有做。但在微软的X64程序设计环境,longjmp启动了正常的"栈卷回"。[4]

    如果setjmp所在的函数已经调用返回了,那么longjmp使用该处setjmp所填写的对应jmp_buf缓冲区将不再有效。这是因为longjmp所要返回的"栈帧"(stack frame)已经不再存在了,程序返回到一个不再存在的执行点,很可能覆盖或者弄坏程序栈.[5][6]

     

    • 简单例子

     

    #include <stdio.h>
    #include <setjmp.h>

    static jmp_buf buf;

    void second(void) {
    printf("second\n"); // 打印
    longjmp(buf,1); // 跳回setjmp的调用处 - 使得setjmp返回值为1
    }

    void first(void) {
    second();
    printf("first\n"); // 不可能执行到此行
    }

    int main() {
    if ( ! setjmp(buf) ) {
    first(); // 进入此行前,setjmp返回0
    } else { // 当longjmp跳转回,setjmp返回1,因此进入此行
    printf("main\n"); // 打印
    }

    return 0;
    }


    上述程序将输出:

    second
    main
    

    注意到虽然first()子程序被调用,"first"不可能被打印。"main"被打印,因为条件语句if ( ! setjmp(buf) )被执行第二次。

     

     

    • 异常处理

     

    在下例中,setjmp被用于包住一个例外处理,类似trylongjmp调用类似于throw语句,允许一个异常返回给setjmp一个异常值。下属代码示例遵从1999 ISO C standardSingle UNIX Specification:仅在特定范围内引用setjmp

    • ifswitch或它们的嵌套使用的条件表达式
    • 上述情况下与!一起使用或者与整数常值比较
    • 作为单独的语句(不使用其返回值)

    遵从上述规则使得创建程序环境缓冲区更为容易。更一般的使用setjmp可能引起未定义的行为,如破坏局部变量;编译器被要求保护或警告这些用法。但轻微的复杂用法如switch ((exception_type = setjmp(env))) { }在文献与实践中是常见的,并保持了相当的可移植性。

    #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() {
    void *volatile 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 */
    }

    展开全文
  • 看书上貌似longjmp设置了第二个参数后,setjmp返回值就自动变成那个值了
  • setjmp

    2013-10-02 22:22:00
    头文件是<setjmp.h> 然后一般定义一个全局jmp_...第一次setjmp(jmp) 返回值为0 第二次setjmp()返回值为longjmp(jmp,value);第二个参数的值value 转载于:https://www.cnblogs.com/ccccccccc/p/3349740.html...
  • 第一次调用setjmp返回值是null 中后续的代码中执行到longjmp以后,longjmp需要两个参数,一个是之前setjmp保存到运行环境的全局变量可以调整到setjmp函数 另一个参数是setjmp函数的返回值,然后程序执行会...
  • setjmp & longjmp

    2013-09-12 16:54:31
    头文件: setjmp.h 函数原型: int setjmp(jmp_buf state);...setjmp和longjmp函数提供了实现类似goto语句的机制,首先声明一个jmp_buf变量,并调用setjmp函数对其初始化,setjmp返回值为0。setjmp吧程序的
  • setjmp longjmp

    2021-05-11 13:59:00
    int setjmp(jmp_buf jmpbuffer); 第一次调用返回值为0,从longjmp调整后setjmp返回非0值,可由longjmp入参retval传递值。 void longjmp(jmp_buf jumpbuffer, int retval);
  • 2018.2.15

    2020-05-06 17:53:28
    2018.2.15 #include <stdio.h> #include <setjmp.h> static jmp_buf buf; void second(void) { printf("second\n"); // 打印 longjmp(buf,1); // 跳回setjmp的调用处 - 使得setjmp返回值...
  • setjmp和longjmp

    2013-01-25 02:12:00
    头文件<setjmp.h>中的声明提供了一种不同于通常的函数调用和返回顺序的方式,特别是,它允许立即...如果直接调用 setjmp,则返回值为 0;如果是在longjmp 中调用 setjmp,则返回值为非 0。setjmp 只是用于某些...
  • setjmp 和 longjmp

    2019-07-12 20:51:40
    一、引入 在C中,goto语句是不能跨越函数的,而执行这样跳转功能的是函数 setjmp 和 longjmp。这两个函数对于处理发生在深层嵌套函数调用中的出错情况是非常有用的。这两个函数也称为非局部 goto,...// 返回值:...
  • 原文地址:何登成的技术博客 ...这个子程序[1] 保存程序的调用环境于env参数所指的缓冲区,env将被longjmp使用。如果是从setjmp直接调用返回,setjmp返回值为0。如果是从longjmp恢复的程序调用环境返回
  • Setjmp 与longjmp

    2015-07-10 10:16:53
    Setjmp 与longjmp 1.这两个函数是c语言特有的函数 2.setjmp-longjmp组合的用处类似于游戏中的存盘读盘功能,经常被用于类似C++的异常恢复操作。 例子演示: //int setjmp(jmp_buf envbuf); //setjmp函数用缓冲区...
  • setjmp函数的简单用途

    2020-02-23 00:31:54
    需要在函数内部进行跳转可以使用goto,在函数之间进行跳转就需要使用setjmp函数 #include <setjmp.h> int setjmp(jmp_buf envbuf);...之后调用longjmp(),longjmp()第二个参数即为setjmp()的返回值。 #...
  • setjmp.h setjmp/longjmp

    2012-06-30 14:35:26
    setjmp.h是C标准函数库中提供“非本地跳转”的头文件:控制流偏离了通常的子程序调用与返回序列。互补的两个函数setjmp与longjmp提供了这种功能。 setjmp/longjmp的典型用途是例外处理机制的实现:利用longjmp恢复...
  • setjmp.h

    千次阅读 2016-05-09 13:42:26
    1、示例代码 #include #include int main() { jmp_buf j;//保存当前环境 ... if(setjmp(j) == 0) { printf("setjmp初始化\n"); longjmp(j,1); printf("不会执行这句话\n"); }
  • 函数定义在setjmp.h中。 int setjmp(jmp_buf buf); setjmp函数用缓冲区buf保存系统堆栈的内容,以便后续的...longjmp函数中的参数buf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。 longj...
  • setjmp longjmp

    2009-10-29 21:10:00
    setjmp和longjmp的函数原型在setjmp.h中。函数原型:int setjmp(jmp_buf envbuf);setjmp函数用缓冲区envbuf保存系统堆栈的内容,以便后续的longjmp函数使用。setjmp函数初次启用时返回0值。 void longjmp(jmp_buf ...
  • setjmp和longjmp goto应用

    2015-06-01 19:28:01
    setjmp(jmp_buf j):使用变量j 记录现在的位置,函数返回0; longjmp(jmp_buf j,int i):回到j ...(不过一般不用返回值,测试后返现返回值赋值提示错误) goto:只能在当前函数内部跳转, setjmp和longjmp可以长
  • C中的setjmp与longjmp

    2015-11-15 09:26:00
    setjmp与longjmp是属于C语言中的,当然,C++也会有这两个函数了。他们的原型如下: int setjmp( jmp_buf env );...=0,则setjmp返回值将设为x。而若x==0,则setjmp返回1。 void longjmp( jmp_b...
  • setjmp 与 longjmp

    2019-09-23 13:11:13
    setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理。 先来看一下这两个函数的定义吧: setjmp和...
  • linux c-setjmp,longjmp

    2013-04-19 13:37:42
    在中,定义了setjmp(jmp_buf ...longjmp函数中的参数envbuf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。longjmp函数本身是没有返回值的,它执行后跳转到保存envbuf参数的setjmp函数调用,并由s
  • setjmp和longjmp的使用

    千次阅读 2013-01-15 16:56:04
    int setjmp(jmp_buf envbuf); setjmp函数用缓冲区envbuf保存系统堆栈的内容,以便后续的longjmp函数使用。...longjmp函数中的参数envbuf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。longjmp函数
  • setjmp ()函数

    2008-12-23 22:44:00
    setjmp 语法: #include int setjmp( jmp_buf envbuf );...当第一次调用setjmp(),它的返回值为零。之后调用longjmp(),longjmp()的第二个参数即为setjmp()的返回值。是否有点疑问?请参阅longjmp().

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,056
精华内容 1,622
关键字:

setjmp返回值