C语言 在包装器函数和局部变量破坏中使用 setjmp



手册页中的 setjmp(3( 文档 (在我的系统上( 指出

所有可访问对象都具有截至调用 longjmp(( 例程时的值,除了自动存储调用持续时间的对象的值不具有易失性类型并且 在 setjmp(( 调用和 longjmp(( 调用之间更改是不确定的。

这是否仅包括与调用setjmp的函数位于同一作用域中的对象,或者还包括调用堆栈上层函数作用域中的任何对象?

例如,以下代码是否正确?

#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
void function_that_longjmps(void)
{
longjmp(env, 1);
}
int setjmp_wrapper(jmp_buf env)
{
if (setjmp(env) == 0)
return 0;
else
return 1;
}
int main()
{
int i = 0;
if (setjmp_wrapper(env) == 0) {
i = 1;
function_that_longjmps();
}
printf("i = %dn", i);
return 0;
}

局部变量isetjmplongjmp调用之间被修改,但它不存在于setjmp_wrapper范围内。在这种情况下,变量是否有可能被破坏?

无论局部变量发生什么情况,您的示例都会表现出未定义的行为,因为您无法longjmp已返回的函数执行。

至于一个不展示 UB 的例子,也许

#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
void calls_longjmp(int *p) {
*p = 1;
longjmp(env);
}
void calls_setjmp(int *p) {
if (setjmp(env)) {
return;
}
calls_longjmp(p);
}
int main(void) {
int x = 0;
calls_setjmp(&x);
printf("%dn", x);
}

那么x保证在longjmp之后具有价值1,而不是0或不确定。引用 C11 N1570 草案:

所有可访问的对象都有值,抽象机器249的所有其他组件(在调用longjmp函数时都有状态,除了包含相应setjmp宏调用的函数的本地自动存储持续时间的对象的值是不确定的,这些对象没有可变限定类型,并且在setjmp调用和longjmp调用之间发生了变化。

最新更新