setjmp与longjmp

来源:互联网 发布:天猫旗舰店网址优化 编辑:程序博客网 时间:2024/05/21 14:20

 

 

今天试了一下setjmp与longjmp的用法:

 

 

这是照着其例子写的一个程序,编译运行通过,并输出:

 

[a@aa]$ ./setjmp

hello fun1

welcome to come back~

 

然而我对代码有一些疑问,为什么setjmp可以改变m_buf 结构里面的内容.

setjmp的声明是这样的  int setjmp(jmp_buf);

从表面上看setjmp是接受一个值类型的参数而不是一个引用类型的参数,参数的类型是jmp_buf,也就是说(从表面上看)jmp_buf类型

的变量在setjmp的函数体里面其实是一份COPY

但是从代码上看setjmp与longjmp却确实是通过 m_buf 这个变量来传递信息的(即在调用setjmp时候的设置当时的环境状态,以供

longjmp跳回去)

 

于是再看了下jmp_buf的定义:

 

 

 

 

jmp_buf其实是用typedef另外声明的别名,它的含义是定义一个__jmp_buf_tag  结构数组,这个数组的大小是1,这样的话就好理解多

了。其实 jmp_buf  m_buf 等于  __jmp_buf_tag    m_buf[1];   那么m_buf其实就是m_buf[1]数组里面的首地址,其值是一个指向首个

 

元素的一个指针。

假如我们在调用函数的时候传入参数后,欲修改参数的内容,可以使用传入地址的方式来实现(引用也可以,原理都一样),就是把参数

的地址给传进去,以便函数体通过参数的地址去修改参数的内容。

 

这样看的话setjmp(jmp_buf buf)其实就是 setjmp( __jmp_buf_tag[]); 该函数接受一个 __jmp_buf_tag  结构体的首地址。

setjmp(m_buf)也就是传入__jmp_buf_tag结构体的首地址(即指针)

所以在调用的时候就可以使用指针去修改其值了。