setjmp 和 longjmp,以及对变量的影响

setjmp/longjmp是用来做non-local goto的。 一般情况下不建议使用。

 

先来看个例子。

#include <sys/types.h>  /* for socket(2) and related bits and pieces */
#include <sys/socket.h> /* for socket(2) */
#include <net/if.h>     /* for struct ifreq */
#include <net/if_arp.h> /* for ARPHRD_ETHER */
#include <sys/ioctl.h>  /* for IOCTL's */
#include <stdio.h>      /* for fprintf etc */
#include <unistd.h>     /* for close */
#include <stdlib.h>
#include <setjmp.h>

static void f1(int, 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;
    int            autoval2;

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

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

    globval =95; autoval = 96; regival = 97; volaval = 98; statval = 99;

    f1( autoval, regival, volaval, statval, &autoval2);
    exit(0);
}

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

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

 

运行结果如下

in f1():
globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99, autoval2 = 0
after longjmp:
globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99, autoval2 = 11
这个结果跟我想象的有点不一样。本来以为会恢复成,1,2,3,4,5的。

 

用优化编译后得到的另一个结果

gcc -O test.c

in f1():
globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99, autoval2 = 0
after longjmp:
globval = 95, autoval = 2, regival = 3, volaval = 98, statval = 99, autoval2 = 0

 

书上的解释如下:

Note that the optimizations don't affect the global, static, and volatile variables;
their values after the longjmp are the last values that they assumed.
The setjmp(3) manual page on one system states that variables stored in memory will
have values as of the time of the longjmp, whereas variables in the CPU and floating-point
registers are restored to their values when setjmp was called.
This is indeed what we see
when we run the program in Figure 7.13. Without optimization, all five variables are stored in memory
(the register hint is ignored for regival). When we enable optimization,
both autoval and regival go into registers, even though the former wasn't declared register,
and the volatile variable stays in memory. The thing to realize with this example is that you
must use the volatile attribute if you're writing portable code that uses nonlocal jumps.
Anything else can change from one system to the next.

 

1. 优化不影响 global, static, volatile变量。

2. 标出来的那句话意思是,保存在内存中的变量,longjmp返回后,保持了longjmp时的值。

    而在cpu中的值将会退回到setjmp时的值。

3. 没有优化时global, static, volatile, auto, register都存在内存中。

    返回的时候,这些值仍然是longjmp时候的值。

    但在有优化的时候, auto, register的值是在寄存器的。

    所以返回的时候,这两个值是在setjmp时候的值。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值