longjmp
来自cppreference.com
| 在标头 <setjmp.h> 定义
|
||
| |
(C11 前) | |
| |
(C11 起) (C23 前) |
|
| |
(C23 起) | |
载入先前调用 setjmp 保存的执行环境 env。此函数不返回。转移控制流到设置 env 的宏 setjmp 的调用方。该 setjmp 会返回作为 status 传递的值。
若调用 setjmp 的函数已退出(通过返回或通过另一到栈上更高处的 longjmp),则行为未定义。换言之,只有调用栈间的长跳转是允许的。
|
跨线程跳转(若调用 |
(C11 起) |
|
若在调用 setjmp 时,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 my_jump_buffer;
noreturn void foo(int status)
{
printf("foo(%d) called\n", status);
longjmp(my_jump_buffer, status + 1); // 将从 setjmp 返回 status+1
}
int main(void)
{
volatile int count = 0; // setjmp 作用域中修改的局部变量必须为 volatile
if (setjmp(my_jump_buffer) != 5) // 在 if 中与常量比较
foo(++count);
}
输出:
foo(1) called
foo(2) called
foo(3) called
foo(4) called
引用
- C17 标准(ISO/IEC 9899:2018):
- 7.13.2.1 The longjmp macro (第 191-192 页)
- C11 标准(ISO/IEC 9899:2011):
- 7.13.2.1 The longjmp macro (第 263-264 页)
- C99 标准(ISO/IEC 9899:1999):
- 7.13.2.1 The longjmp macro (第 244-245 页)
- C89/C90 标准(ISO/IEC 9899:1990):
- 4.6.2.1 The longjmp function
参阅
| 保存上下文 (宏函数) | |
longjmp 的 C++ 文档
| |