【GNU笔记】【C扩展系列】非局部Goto Nonlocal Gotos
非局部Goto Nonlocal Gotos
GCC提供了内置函数__builtin_setjmp
和__builtin_longjmp
,它们与C库函数setjmp
和longjmp
类似,但不能互换。内置版本被GCC的库内部使用,用于在某些目标上实现异常处理。你应该在用户代码中使用<setjmp.h>
中声明的标准C库函数,而不是内置版本。
这些函数的内置版本使用GCC的正常机制,在函数进入和退出时使用堆栈保存和恢复寄存器。跳转缓冲区的参数buf只保存恢复堆栈帧所需的信息,而不是保存的整个寄存器值的集合。
一个重要的警告是,GCC只安排保存和恢复那些被编译的特定架构变量的寄存器。这可以使__builtin_setjmp
和__builtin_longjmp
在某些情况下比它们的对应库更有效,但它也可能在与使用全部寄存器集的代码混合时,引起不正确和神秘的行为。
你应该将跳转缓冲区参数buf声明为内置函数:
#include <stdint.h>
intptr_t buf [5];
-
内置函数:int __builtin_setjmp (intptr_t * buf )
这个函数将当前的堆栈上下文保存在buf中。当直接返回时,
__builtin_setjmp
返回 0,而当使用相同的 buf 从__builtin_longjmp
返回时,返回 1。 -
内置函数:void __builtin_longjmp (intptr_t * buf , int val )
这个函数恢复了buf中的堆栈上下文,这个堆栈上下文是由先前调用
__builtin_setjmp
保存的。在__builtin_longjmp
完成后,程序恢复执行,就像匹配的__builtin_setjmp
返回值val一样,这个值必须是1。因为
__builtin_longjmp
依赖于函数的返回机制来恢复堆栈上下文,它不能从调用__builtin_setjmp
来初始化 buf 的同一个函数中调用。它只能从调用__builtin_setjmp
的函数中调用(直接或间接)。