命名空间
变体
操作

longjmp

来自 cppreference.com
< 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++ 文档 针对 longjmp