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

来源:互联网 发布:学而思当美工工资高吗 编辑:程序博客网 时间:2024/06/05 08:06
[root@bogon code]# cat c.c#include<stdio.h>#include<setjmp.h>static jmp_buf env;//定义全局变量envvoid 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.outthis is from no parameter work()[root@bogon code]# ./a.out 32this 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.outa is 100b is 200c is 300[root@bogon code]# gcc -O c.c//使用选项-O进行编译优化,所以有重置[root@bogon code]# ./a.outa is 10b is 20c is 300[root@bogon code]# 

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