当前位置: C语言 -- 标准库 -- <setjmp.h> -- setjmp

setjmp宏


概要:
#include <setjmp.h>
int setjmp(jmp_buf env);

描述:

该宏将调用环境保存在参数env中,供后续longjmp函数调用使用。

setjmp究竟是宏还是具有外部链接的标识符,ISO/IEC 9899:2018标准未作明确说明。如果为了访问实际函数而禁止宏setjmp定义,或者程序定义了名为setjmp的外部标识符,其行为是未定义的。


setjmp只能在以下情况使用:

- 选择或者迭代语句的整个控制表达式,例如:if(setjmp(env))

- 关系运算符或者相等运算符的操作数,与另一个操作数构成整型常量表达式,结果表达式是选择或者迭代语句的整个控制表达式,例如:if(setjmp(env)==0)

- 运算符!的操作数,结果表达式是选择或者迭代语句的整个控制表达式,例如:if(!setjmp(env))

- 表达式语句的整个表达式(可能映射为void类型),例如:setjmp(env);

其它情况下调用宏setjmp,行为是未定义的。


参数:
jmp_buf env

该参数保存调用环境的相关信息。


返回值:

如果直接调用宏setjmp,将返回0;如果通过longjmp函数调用获取返回值,将返回一个非0值。


范例:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
/*宏setjmp范例*/

#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>

jmp_buf environment;

_Noreturn void func(void)
{
    puts("The code before the longjmp function in the func function will be executed.");
    longjmp(environment, 1);

    /*func函数中以下代码不会被执行。*/
    puts("The code after the longjmp function in the func function should never be executed.");
}

int main(void)
{
    if(setjmp(environment))
    {
        puts("The longjmp function has been called.");
        exit(EXIT_FAILURE);
    }

    puts("The setjmp macro has been called.");
    puts("Call the func function.");
    func();

    /*main函数中以下代码不会被执行。*/
    puts("The code after the func function in the main function should never be executed.");

    return 0;
}


输出:

The setjmp macro has been called.

Call the func function.

The code before the longjmp function in the func function will be executed.

The longjmp function has been called.


该程序首先评估if语句的控制表达式setjmp(environment),这次返回值来自宏setjmp的直接调用,所以值为0;接着执行第2627行语句,然后调用func函数;执行longjmp(environment, 1);语句后,程序跳转至main函数的setjmp(environment)处;再次评估控制表达式setjmp(environment),这次返回值来自longjmp(environment, 1)函数调用,所以返回值为1;最后执行第2223行语句。


相关内容:
jmp_buf 保存调用环境相关信息的类型。
longjmp 恢复调用环境的函数。