如何从主函数使用longjmp到其他函数?

How to use longjmp from main function to other functions?

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

jmp_buf jmp;

int test() {
    setjmp(jmp);
    puts("Birds are crying");
    return 0;
}


int main() {
    longjmp(jmp,1);
    return 0;
}

以上代码无法运行并崩溃,为什么?

我在 Windows 10 Pro 上使用 GCC 编译器。

你对longjmp()的用法无效,看看the documentation:

longjmp() restores the environment saved by the last call of setjmp()

您需要先调用 setjmp(),以便在 调用 longjump() 之前“设置”跳转的位置 。这就是为什么您的代码不起作用的原因。这充其量是未定义的行为。

换句话说,您不能只使用 longjmp() 作为简单的“跳转到全局标签”。它有不同的用途。


after putting test(); call before the line longjmp it works and print it twice but why does it still crashes?

我们再来看看the documentation:

setjmp() saves the stack context/environment in env for later use by longjmp(). The stack context will be invalidated if the function which called setjmp() returns.

您不能 longjmp() 到先前由现在已返回的函数设置的缓冲区。这是无效的。您对 setjmp()/longjmp() 的使用实际上并不是这些函数的用途。


跳转到另一个函数并不是setjmp()/longjmp()的真正目的,它们的目的是保存上下文并“跳回”到一个还没有返回的函数(见下面的例子)。想出这些函数的有意义的示例用法并不容易,因为它们是为高级用法而设计的。

这是一个正确的用法示例(虽然仍然没有那么有意义)from Wikipedia:

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

static jmp_buf buf;

void second() {
    printf("second\n");         // prints
    longjmp(buf,1);             // jumps back to where setjmp was called - making setjmp now return 1
}

void first() {
    second();
    printf("first\n");          // does not print
}

int main() {   
    if (!setjmp(buf))
        first();                // when executed, setjmp returned 0
    else                        // when longjmp jumps back, setjmp returns 1
        printf("main\n");       // prints

    return 0;
}