命名空间
变体
操作

longjmp

来自 cppreference.cn
< c‎ | program
定义于头文件 <setjmp.h>
void longjmp( jmp_buf env, int status );
(C11 之前)
_Noreturn void longjmp( jmp_buf env, int status );
(C11 起)
(直至 C23)
[[noreturn]] void longjmp( jmp_buf env, int status );
(自 C23 起)

加载由之前调用 setjmp 保存的执行上下文 env。此函数不返回。控制转移到设置 env 的宏 setjmp 的调用位置。该 setjmp 随后返回作为 status 传递的值。

如果调用 setjmp 的函数已退出(无论是通过返回还是通过堆栈中更高位置的不同 longjmp),则行为未定义。换句话说,只允许在调用堆栈中向上进行长跳转。

跨线程跳转(如果调用 setjmp 的函数由另一个线程执行)也是未定义行为。

(C11 起)

如果在调用 setjmp 时,可变长数组(VLA) 或另一个 可变修改类型 变量在作用域内,并且控制离开了该作用域,则 longjmp 到该 setjmp 会导致未定义行为,即使控制仍在函数内。

在堆栈向上回溯时,longjmp 不会释放任何 VLA,如果它们的生命周期以这种方式终止,可能会发生内存泄漏

void g(int n)
{
    int a[n]; // a may remain allocated
    h(n); // does not return
}
void h(int n)
{
    int b[n]; // b may remain allocated
    longjmp(buf, 2); // might cause a memory leak for h's b and g's a
}
(C99 起)

目录

[编辑] 参数

env - 引用由 setjmp 保存的程序执行状态的变量
status - setjmp 返回的值。如果它等于 0,则改用 1

[编辑] 返回值

(无)

[编辑] 注意

longjmp 旨在处理函数无法有意义地返回的意外错误情况。这类似于其他编程语言中的异常处理。

[编辑] 示例

#include <stdio.h>
#include <setjmp.h>
#include <stdnoreturn.h>
 
jmp_buf my_jump_buffer;
 
noreturn void foo(int status) 
{
    printf("foo(%d) called\n", status);
    longjmp(my_jump_buffer, status + 1); // will return status+1 out of setjmp
}
 
int main(void)
{
    volatile int count = 0; // modified local vars in setjmp scope must be volatile
    if (setjmp(my_jump_buffer) != 5) // compare against constant in an if
        foo(++count);
}

输出

foo(1) called
foo(2) called
foo(3) called
foo(4) called

[编辑] 参考

  • C17 标准 (ISO/IEC 9899:2018)
  • 7.13.2.1 longjmp 宏 (p: 191-192)
  • C11 标准 (ISO/IEC 9899:2011)
  • 7.13.2.1 longjmp 宏 (p: 263-264)
  • C99 标准 (ISO/IEC 9899:1999)
  • 7.13.2.1 longjmp 宏 (p: 244-245)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 4.6.2.1 longjmp 函数

[编辑] 另请参阅

保存上下文
(函数宏) [编辑]
C++ 文档 for longjmp