包装setjmp和longjmp有什么奇怪的?

Max*_*Max 4 c gcc exception-handling

我第一次使用setjmp和longjmp,我遇到了一个问题,当我包装setjmp和longjmp时.我将代码煮成以下示例:

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

jmp_buf jb;

int mywrap_save()
{
  int i = setjmp(jb);
  return i;
}

int mywrap_call()
{
  longjmp(jb, 1);
  printf("this shouldn't appear\n");
}

void example_wrap()
{
  if (mywrap_save() == 0){
    printf("wrap: try block\n");
    mywrap_call();
  } else {
    printf("wrap: catch block\n");
  }
}

void example_non_wrap()
{
  if (setjmp(jb) == 0){
    printf("non_wrap: try block\n");
    longjmp(jb, 1);
  }  else {
    printf("non_wrap: catch block\n");
  }
}

int main()
{
  example_wrap();
  example_non_wrap();
}
Run Code Online (Sandbox Code Playgroud)

最初我认为example_wrap()和example_non_wrap()的行为相同.但是,运行程序的结果(GCC 4.4,Linux):

wrap: try block
non_wrap: try block
non_wrap: catch block
Run Code Online (Sandbox Code Playgroud)

如果我在gdb中跟踪程序,我看到即使mywrap_save()返回1,返回后的else分支也会被奇怪地忽略.谁能解释一下发生了什么?

Whi*_*ind 10

 The longjmp() routines may not be called after the routine which called
 the setjmp() routines returns.
Run Code Online (Sandbox Code Playgroud)

换句话说,你搞砸了你的筹码.

您可以查看程序集,看看是否可以拼凑出真正发生的事情.