gpt4 book ai didi

c - 为什么setjmp/longjmp

转载 作者:行者123 更新时间:2023-12-04 12:09:06 24 4
gpt4 key购买 nike

我想使用 setjmp/longjmp 在主函数中重用一些代码(注意:这只是一个练习,而不是我在现实世界中认真计划做的事情)。
以下代码是我想出的:

#include <stdio.h>
#include <setjmp.h>
jmp_buf jmp_body, jmp_ret;

void func(void)
{
if (setjmp(jmp_ret) == 0)
longjmp(jmp_body, 1);
}

int main()
{
int x = 0;
if (setjmp(jmp_body) == 1) {
printf("Body %d\n", ++x);
longjmp(jmp_ret, 1);
}
func();
func();
func();
return 0;
}
我期望此代码的工作方式如下:
  • main()函数将记住“主体”部分的位置并使用 if (setjmp(jmp_body) == 1) 跳过它.
  • func()调用将使用 longjmp(jmp_body) 暂时跳转到正文在使用 if (setjmp(jmp_ret) == 0) 记住 body 应该返回的位置后
  • body 将要执行并跳回 func()使用 longjmp(jmp_ret, 1) 拨打电话
  • func()刚要回main()正如预期的那样。

  • 因此,我期望打印的代码如下:
    Body 1
    Body 2
    Body 3
    相反,它永远循环不断地执行向我指示 func() 的主体。 call 没有返回它应该返回的位置,而是可能返回到自身之上,一遍又一遍地执行自己。
    相比之下,以下代码打印的正是我所期望的:
    #include <stdio.h>
    #include <setjmp.h>
    jmp_buf jmp_body, jmp_ret;

    int main()
    {
    int x = 0;
    if (setjmp(jmp_body) == 1) {
    printf("Body %d\n", ++x);
    longjmp(jmp_ret, 1);
    }
    if (setjmp(jmp_ret) == 0)
    longjmp(jmp_body, 1);
    if (setjmp(jmp_ret) == 0)
    longjmp(jmp_body, 1);
    if (setjmp(jmp_ret) == 0)
    longjmp(jmp_body, 1);
    return 0;
    }
    什么是放 if (setjmp(jmp_ret) == 0) longjmp(jmp_body, 1)在使原始方法无效的函数调用中?

    最佳答案

    TL/DR - 你不能跳回你跳出的函数。

    7.13.2.1 The longjmp function
    ...
    2     The longjmp function restores the environment saved by the most recent invocation ofthe setjmp macro in the same invocation of the program with the corresponding jmp_buf argument. If there has been no such invocation, or if the invocation was fromanother thread of execution, or if the function containing the invocation of the setjmpmacro has terminated execution248) in the interim, or if the invocation of the setjmpmacro was within the scope of an identifier with variably modified type and execution hasleft that scope in the interim, the behavior is undefined.
    248) For example, by executing a return statement or because another longjmp call has caused atransfer to a setjmp invocation in a function earlier in the set of nested calls.

    C 2011 Online Draft
    当你执行 longjmp(jump_body, 1);func , 你无效 jump_ret . longjmp不是双向的 - 它展开堆栈,就像 setjmp 之间的任何函数调用一样和 longjmp从来没有发生过。

    关于c - 为什么setjmp/longjmp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68395378/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com