longjmp

来自cppreference.com
< c‎ | program
定义于头文件 <setjmp.h>
void longjmp( jmp_buf env, int status );
(C11前)
_Noreturn void longjmp( jmp_buf env, int status );
(C11起)

载入先前setjmp的调用所保存的执行语境env。此函数不返回。控制流被转移到设置env的宏setjmp的调用方。该setjmp会返回status所传递的值。

若调用setjmp的函数已经退出了(通过返回或通过另一到栈上更高处的longjmp),则行为未定义。换言之,只有调用栈间的长跳转是允许的。

跨线程(若调用setjmp的函数被另一线程执行)亦是未定义行为。

(C11起)

若在调用setjmp时,VLA或其他可变修改类型变量在作用域中,并且控制流离开了该作用域,则longjmp到该setjmp将发起未定义行为,即使控制流仍然留在该函数内。

在上溯栈的途中,longjmp不会返还任何VLA,若他们的生存期以此方式终结,则会出现内存泄漏:

void g(int n)
{
    int a[n]; // a仍为已分配
    h(n); // 不返回
}
void h(int n)
{
    int b[n]; // b仍为已分配
    longjmp(buf, 2); // 可能因为h的b和g的a导致内存泄漏
}
(C99起)

目录

[编辑] 参数

env - 引用setjmp所保存的程序执行状态的变量
status - 要从setjmp返回的值。若它等于0,则以1替代使用

[编辑] 返回值

(无)

[编辑] 注意

longjmp是打算用来处理没有期待到的错误条件的,在该条件下函数无法有意义地返回。这与其他程序语言中的异常处理相似。

[编辑] 示例

#include <stdio.h>
#include <setjmp.h>
#include <stdnoreturn.h>
 
jmp_buf jump_buffer;
 
noreturn void a(int count) 
{
    printf("a(%d) called\n", count);
    longjmp(jump_buffer, count+1); // 将在setjmp外返回count+1
}
 
int main(void)
{
    volatile int count = 0; // 必须为setjmp声明volatile变量
    if (setjmp(jump_buffer) != 9)
        a(count++);
}

输出:

a(0) called
a(1) called
a(2) called
a(3) called
a(4) called
a(5) called
a(6) called
a(7) called
a(8) called

[编辑] 参考

  • C11 standard (ISO/IEC 9899:2011):
  • 7.13.2.1 The longjmp macro (p: 263-264)
  • C99 standard (ISO/IEC 9899:1999):
  • 7.13.2.1 The longjmp macro (p: 244-245)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 4.6.2.1 The longjmp function

[编辑] 参阅

保存语境
(宏函数) [edit]
longjmpC++文档