命名空间
变体
操作

longjmp

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

加载先前调用 setjmp 保存的执行上下文 env。此函数不返回。控制权转移到设置 env 的宏 setjmp 的调用点。然后,setjmp 返回作为 status 传递的值。

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

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

(since 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
}
(since 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