您好我想问一下setjmp / longjmp。我试图搜索,但我没有用...
#include <stdio.h>
#include <setjmp.h>
jmp_buf a, b;
void jump() {
int aa = setjmp(a);
if (aa)
{
printf("Jump!\n");
}
else
{
longjmp(b, 1);
printf("Should not happened...\n");
}
printf("End of function!\n");
}
int main(int argc, char** argv) {
int bb = setjmp(b);
if (bb)
{
longjmp(a, 1);
printf("Should not happened...\n");
}
else
{
jump();
printf("What here?\n");
}
printf("Exit\n");
return 0;
}
问题是,在jump()中的最后一个printf之后会发生什么...我尝试了这个代码,它变成了无限循环。为什么?我虽然setjmp会存储环境数据,所以跳转函数应该在它原始调用之后返回...我很安静。谢谢你的回复:)
答案 0 :(得分:2)
整个程序有不确定的行为。
setjmp(b);
存储堆栈状态。jump()
被召唤。longjmp(b, 1);
将堆栈恢复到调用jump()
之前的点。因此,a
中存储的状态现在无效。if
中的main()
继续执行。longjmp(a, 1);
被调用。哎哟。由于上面的4,这导致了未定义的行为。 您的混淆可能是因为setjmp()
的Linux文档中使用世界“返回”的略微不精确。
如果调用
setjmp()
的函数返回,则堆栈上下文将无效。
在您的示例中,函数jump()
没有以正常方式返回,但效果是相同的:堆栈被第一个longjmp()
“切断”到{{之前的状态1}},这也是回报的作用。