我想使用 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)
setjmp的手册页说:
setjmp()保存堆栈上下文/环境以env供以后使用longjmp().如果调用的函数setjmp()返回,则堆栈上下文将无效.
在一个简单的实现中,你可能会认为a jmp_buf包含一个地址来重置堆栈指针和一个跳转到的地址.一旦从保存的函数返回jmp_buf,则指向的堆栈帧jmp_buf不再有效,并且可能立即被破坏.
换句话说,你只能依靠longjmp作为一种超级return声明 - 永远不要深入.
我认为这对你来说在mingw(以及我在Linux上)的作用的原因是特定于实现的,可能还有运气.还有另外一种方法 - 你读过西蒙塔特姆的邪恶的协程宏文章吗?