setjmp和longjmp

1.goto只能实现函数内部跳转,而longjmp可以实现函数之间的安全跳转(只有一种情况不安全)

2.setjmp

    setjmp, sigsetjmp - save stack context for nonlocal goto

SYNOPSIS
    #include <setjmp.h>

    int setjmp(jmp_buf env);

①这个函数是保存返回点的信息,保存到jmp_buf这个结构体当中
②他有两个返回值 一个是设置返回点 返回值是 0 ;另外一个是返回了,返回值由longjmp决定 非0

3.longjmp

   longjmp, siglongjmp - nonlocal jump to a saved stack context

SYNOPSIS
   #include <setjmp.h>

   void longjmp(jmp_buf env, int val);

①这个value就决定了返回点的 返回值
②这里可以看出 通常要将jmp_buf这个结构体 定义为全局变量
③If longjmp() is invoked with a second argument of 0, 1 will be
returned instead

4. 一个测试Demo

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


jmp_buf JmpBuf;

void D(void)
{

        printf("%s(): Begin\n", __FUNCTION__);
        printf("%s(): End\n", __FUNCTION__);

}


void C(void)
{
        printf("%s(): Begin\n", __FUNCTION__);
        printf("%s(): Call D()\n", __FUNCTION__);
        D();
        printf("%s(): Return D()\n", __FUNCTION__);
        printf("%s(): End\n", __FUNCTION__);
}



void B(void)
{
        printf("%s(): Begin\n", __FUNCTION__);
        printf("%s(): Call C()\n", __FUNCTION__);
        C();
        printf("%s(): Return C()\n", __FUNCTION__);
        printf("%s(): End\n", __FUNCTION__);

}




void A(void)
{


        printf("%s(): Begin\n", __FUNCTION__);
        printf("%s(): Call B()\n", __FUNCTION__);
        B();
        printf("%s(): Return B()\n", __FUNCTION__);
        printf("%s(): End\n", __FUNCTION__);

}

int main(int argc, char **argv)
{


        printf("%s(): Begin\n", __FUNCTION__);
        printf("%s(): Call A()\n", __FUNCTION__);
        A();
        printf("%s(): Return A()\n", __FUNCTION__);
        printf("%s(): End\n", __FUNCTION__);

        return 0;
}

结果
在这里插入图片描述
进行jmp

void A(void)
{

        int res;

        printf("%s(): Begin\n", __FUNCTION__);
        printf("%s(): Call B()\n", __FUNCTION__);

        res = setjmp(JmpBuf);
        if(0 == res)
        {
                B();
                printf("%s(): Return B()\n", __FUNCTION__);
                printf("%s(): End\n", __FUNCTION__);
        }
        else
        {
                printf("%s(): Longjmp from code %d\n", __FUNCTION__, res);
        }
}


void D(void)
{

        printf("%s(): Begin\n", __FUNCTION__);
        printf("%s(): End\n", __FUNCTION__);
        longjmp(JmpBuf, 6);

}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值