zoukankan      html  css  js  c++  java
  • 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()
    ");//不带程序参数的输出
                break;
            case 2:
                printf("this is from have parameter job()
    ");//带程序参数的输出
                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
    b is %d
    c is %d
    ",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一样

  • 相关阅读:
    prometheus学习系列三:node_exporter安装部署
    prometheus学习系列一: Prometheus简介
    prometheus学习系列二: Prometheus安装
    crontab定时任务不执行,单独运行sh生效
    glusterfs+heketi为k8s提供共享存储
    kubernetes的安装方法
    阿里云负载均衡权重管理脚本
    ldap配置系列二:jenkins集成ldap
    ldap配置系列一:ldap的安装
    ldap配置系列三:grafana集成ldap
  • 原文地址:https://www.cnblogs.com/biaopei/p/7730627.html
Copyright © 2011-2022 走看看