打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
c语言中setjmp与longjmp(3)
分类: C/c++ L 2010-11-29 08:51 485人阅读 评论(1) 收藏 举报

longjmp对自动,寄存器,全局变量,静态变量,和易失变量(Volatile Variable)的影响

 

当longjmp返回到main函数时,这些变量的值是否能恢复到以前调用setjmp时的值(即滚回原先值),或者这些
变量的值保持为最新的值?不幸的是,对此问题的回答是“看情况”。大多数实现并不滚回这些自动变量和寄存器变量的值,而所有标准则说它们的值是不确定的。如果你有一个自动变量,而又不想使其值滚回,则可定义其为具有volatile属性。说明为全局和静态变量的值在执行longjmp时保持不变。

一下是APUE中的例子:
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

static void f1(int, int, int, int);
//static void f2(void);

static jmp_buf jmpbuffer;
static int globval;

int main(void)
{
     int autoval;
     register int regival;
     volatile int volaval;
     static int statval;

     globval = 1; autoval = 2; regival = 3; volaval = 4; statval = 5;

     if (setjmp(jmpbuffer) != 0) {
         printf("after longjmp:/n");
         printf("globval = %d, autoval = %d, regival = %d,"
             " volaval = %d, statval = %d/n",
             globval, autoval, regival, volaval, statval);
         exit(0);
     }

     /*
      * Change variables after setjmp, but before longjmp.
      */
     globval = 95; autoval = 96; regival = 97; volaval = 98;
     statval = 99;

     f1(autoval, regival, volaval, statval); /* never returns */
     exit(0);
}

static void f1(int i, int j, int k, int l)
{
    printf("in f1():/n");
    printf("globval = %d, autoval = %d, regival = %d,"
        " volaval = %d, statval = %d/n", globval, i, j, k, l);
       
    //f2();

    longjmp(jmpbuffer, 1);
}

static void f2(void)
{
    longjmp(jmpbuffer, 1);
}

如果以不带优化和带优化选项对此程序分别进行编译,然后运行它们,则得到不同的结果:


$ cc testjmp.c               compile without any optimization
    $ ./a.out
    in f1():
    globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99
    after longjmp:
    globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99
   

$ cc -O testjmp.c            compile with full optimization
    $ ./a.out
    in f1():
    globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99
    after longjmp:
    globval = 95, autoval = 2, regival = 3, volaval = 98, statval = 99

注意,易失变量(sum)不受优化的影响,在longjmp之后的值,是它在调用f1时的值。在我们所使用的setjmp(3)手册页上说明存放在存储器中的变量将具有longjmp时的值,而在CPU和浮点寄存器中的变量则恢复为调用setjmp时的值。这确实就是在运行以上程序时所观察到的值。不进行优化时,所有这三个变量都存放在存储器中(亦即对val的寄存器存储类被忽略)。而进行优化时,count和val都存放在寄存器中(即使count并末说明为register),volatile变量则仍存放在存储器中。通过这一例子要理解的是,如果要编写一个使用非局部跳转的可移植程序,则必须使用volatile属性。

更多0
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
setjmp 和 longjmp,以及对变量的影响
c函数库中的longjmp与setjmp函数的用法
C语言标准库所包含的函数功能介绍(3)
程序的运行时 数据结构
使用setjmp和longjmp实现程序非本地跳转
C标准库函数浅析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服