• setjmp和longjmp函数


      关于setjmp函数和longjmp函数有话要说,是UNIX高级环境变成看到了10.10信号那章用到了,研究一下,这里作为补充。

      setjmp(jmp_buf env_buf) 函数可以将当前的运行环境存入jmp_buf变量中,函数默认返回值是返回0。直到longjmp修改该值(!0)后会调回setjmp函数处。

      jmp_buf,是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。

      那么,当jmp回来后原函数定义的变量是怎样变化的捏??(答案是:不一定)这里又用几个不同类型的变量来看一下。+编译器优化对运行结果产生的影响。

      代码如下:

    #include <stdio.h>
    #include <setjmp.h>
    
    static jmp_buf jmp_env;
    
    static void f1(int ,int ,int , int );
    static void f2(void);
    
    static int globval = 1;
    
    
    int main(void)
    {
        /* 4 kinds variables*/
        int autoval = 2;
        register int regival = 3;
        volatile int volaval = 4;
        static int statval = 5;
        int retval;
        if ( retval = setjmp(jmp_env) ){     /* default value is 0,  so this will run when returns from longjmp()*/
            printf("after longjmp: %d
    ", retval);  
                     printf("globval=%d,autoval=%d,regival=%d,volaval=%d,statval=%d
    ",globval,autoval,regival,volaval,statval);  
            //exit(0);
            return 0;  
        }
        /*
         * Change variables's value before calc longjmp.
         */
        globval = 101; autoval = 102; regival = 103; volaval = 104; statval = 105;
        f1(autoval, regival, volaval, statval);
        return 0;
    }
    
    static void f1(int i,int j,int k, int l)  
    {  
            printf("in f1():
    ");  
            printf("globval=%d,autoval=%d,regival=%d,volaval=%d,statval=%d
    ",globval,i,j,k,l);  
            f2();  
    }  
    
    static void f2()
    {
        printf("in f2():
    ");
        longjmp(jmp_env, 123);
    }

    结果如下:

      分析一下:gcc 直接编译没有进行优化,所有变量都会被更改;

           gcc -O  使用编译器优化,其中一种优化包括使用寄存器中的int值来读取,而不是去存储器中读变量。导致这里取到的普通局部变量和寄存器变量是之前的值,并不是更新之后的最新值。

      大多实现并不回滚到这些自动变量和寄存器变量的值,不想使其回滚的话有两种方法:

        1.声明为静态变量static

        2.声明为全局变量

        3.声明为volatile变量(volatile)作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。这是用来防编译器优化的!!!如果要

         编写一个非局部跳转的可移植程序必须要使用volaitle关键字

          

        

  • 相关阅读:
    JavaScript 把函数作为参数进行传值
    面向微服务的企业云计算架构转型
    bzoj1009 GT考试 (kmp+矩阵优化dp)
    noiac64 sort (二分答案)
    luogu1983 车站分级 (拓扑排序)
    loj6157 A ^ BProblem (并查集)
    bzoj1831 逆序对 (dp+树状数组)
    luogu2282/bzoj1219 历史年份 (dp+hash+二分+线段树)
    bzoj3702/bzoj2212 二叉树 (线段树合并)
    cf1073G Yet Another LCP Problem (SA+权值线段树)
  • 原文地址:https://www.cnblogs.com/luntai/p/6171149.html
Copyright © 2020-2023  润新知