为什么setjmp/longjmp在MinGW中没有时会在MSVC上崩溃?

TZW*_*TZW 5 c setjmp

我想使用 setjmp()/ longjmp()来实现一个协程系统.然后我决定编写一个.c文件来测试它.在MinGW,没关系; 我得到了我想要的结果.但是当我在MSVC++中编译它时,程序崩溃:"访问冲突"

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

    jmp_buf a;
    int is_invoke=0;

    void 
    action_1()
    {
        for ( ;; ) {
          printf("hello~~~A\n");
          if(!setjmp(a)) {
            is_invoke=1;
            return;
          }  
        }
    }

    void 
    func()
    {
      if (is_invoke) {
        longjmp(a,1);
      }
      action_1();
      printf("end\n");
    }

    void 
    dummy()
    {
      ;
    }

    int 
    main(int argc, char *argv[])
    {
        for ( ;; )  {
          func();
          dummy();
        }
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

cra*_*cot 7

setjmp的手册页说:

setjmp()保存堆栈上下文/环境以env供以后使用 longjmp().如果调用的函数setjmp()返回,则堆栈上下文将无效.

在一个简单的实现中,你可能会认为a jmp_buf包含一个地址来重置堆栈指针和一个跳转到的地址.一旦从保存的函数返回jmp_buf,则指向的堆栈帧jmp_buf不再有效,并且可能立即被破坏.

换句话说,你只能依靠longjmp作为一种超级return声明 - 永远不要深入.

我认为这对你来说在mingw(以及我在Linux上)的作用的原因是特定于实现的,可能还有运气.还有另外一种方法 - 你读过西蒙塔特姆的邪恶的协程宏文章吗?