0

嗨,我想问一下 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 将存储环境数据,所以跳转函数将在它的原始调用后返回......我很困惑。谢谢您的回复 :)

4

1 回答 1

2

整个程序具有未定义的行为。

  1. setjmp(b);存储堆栈状态。
  2. jump()叫做。
  3. `setjmp(a);' 再次存储堆栈状态。
  4. longjmp(b, 1);将堆栈恢复到之前jump()被调用的位置。所以存储的状态a现在是无效的。
  5. 执行在ifin处继续main()
  6. longjmp(a, 1);叫做。哎哟。由于上述 4,这会导致未定义的行为。

您的困惑可能是由于 Linux 文档中对setjmp().

setjmp()如果调用的函数返回,堆栈上下文将失效。

在您的示例中,该函数jump()没有以正常方式返回,但效果是相同的:堆栈被第一个“切碎”longjmp()到之前的状态jump(),这也是 return 的作用。

于 2014-01-25T15:18:36.543 回答