联机帮助页(在我的系统上)中的setjmp(3)文档说明了
所有可访问的对象都具有调用longjmp()例程时的值,除了自动存储调用持续时间的对象值没有volatile类型且已被 在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 = %d\n", i);
return 0;
}
在i
和setjmp
调用之间修改了局部变量longjmp
,但它在setjmp_wrapper
的范围内不存在。在这种情况下,变量是否有可能被破坏?
答案 0 :(得分:4)
您的示例展示了未定义的行为,无论局部变量发生了什么,因为您不能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("%d\n", x);
}
然后x
保证在1
之后具有值0
,而不是longjmp
或不确定。引用C11 N1570 draft:
所有可访问的对象都有值,并且抽象机器 249)的所有其他组件都具有调用longjmp函数时的状态,除了自动存储持续时间的对象的值< strong>包含调用相应setjmp宏的函数的本地函数,它没有volatile限定类型,并且在setjmp调用和longjmp调用之间已经更改,这是不确定的。