setjmp和longjmp函数可以实现函数之间的跳跃(goto),下面是一个实例
#include <stdio.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); } globval = 95; autoval = 96; regival = 97; volaval = 98; statval = 99; f1(autoval, regival, volaval, statval); 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(); } static void f2() { longjmp(jmpbuffer, 1); }
jay@jay-vibox:~/workspace/UNIX/7-6$ cc main.c
main.c: In function ‘main’:
main.c:28:3: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
main.c:38:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
jay@jay-vibox:~/workspace/UNIX/7-6$ ./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
jay@jay-vibox:~/workspace/UNIX/7-6$
然后使用优化编译后执行
jay@jay-vibox:~/workspace/UNIX/7-6$ cc -O main.c
main.c: In function ‘main’:
main.c:28:3: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
main.c:38:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
jay@jay-vibox:~/workspace/UNIX/7-6$ ./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
jay@jay-vibox:~/workspace/UNIX/7-6$
可以发现2次输出不一样,不进行优化时,所有5个变量都存放在存储器中。而进行了优化后,autoval和regival都存放在寄存器中,volatile变量则仍存放在存储器中。
如果要编写一个使用非局部跳转的可移植程序,则必须使用volatile属性。