setjmp与longjmp非局部跳转函数的使用

[root@bogon code]# cat c.c
#include<stdio.h>
#include<setjmp.h>
static jmp_buf env;//定义全局变量env
void job()
{
    longjmp(env,2);//会返回到setjmp(env)处,且返回值为2
}
void work(int argc)
{
    if(argc==1)//没有参数
        longjmp(env,1);//返回到setjmp(env)处,返回值为1
    job();//有参数调用job()
}
int main(int argc,char *argv[])
{
    switch(setjmp(env))//setjmp(env)初始值为0
    {
        case 0:
            work(argc);//传参数个数过去,argc为1代表没有参数
            break;
        case 1:
            printf("this is from no parameter work()\n");//不带程序参数的输出
            break;
        case 2:
            printf("this is from have parameter job()\n");//带程序参数的输出
            break;
    }
    return 0;
}
[root@bogon code]# gcc c.c
[root@bogon code]# ./a.out
this is from no parameter work()
[root@bogon code]# ./a.out 32
this is from have parameter job()
[root@bogon code]# 

这里写图片描述
现在我们来看一下优化编译器问题

[root@bogon code]# cat c.c
#include<stdio.h>
#include<stdlib.h>
#include<setjmp.h>
static jmp_buf env;
void work(int a,int b,int c)
{
    longjmp(env,1);
}
int main(int argc,char *argv[])
{
    int a;
    register int b;
    volatile int c;//将变量声明为volatile,那么编译优化时,该变量的值(300)不会在调用longjmp函数后,重置为setjmp函数调用前的值(30),而其他类型的变量都会重置
    a=10;
    b=20;
    c=30;
    if(setjmp(env)==0)
    {
        a=100;
        b=200;
        c=300;
        work(a,b,c);
    }
    else
        printf("a is %d\nb is %d\nc is %d\n",a,b,c);
    return 0;
}
[root@bogon code]# gcc c.c//没有进行编译优化,所以都没有重置
[root@bogon code]# ./a.out
a is 100
b is 200
c is 300
[root@bogon code]# gcc -O c.c//使用选项-O进行编译优化,所以有重置
[root@bogon code]# ./a.out
a is 10
b is 20
c is 300
[root@bogon code]# 

为了使程序便于维护,还是应当尽量避免使用setjmp和longjmp,不过有时候在恰当的地方,其用处还是很大的,另外我们还应该限制使用goto一样

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值