【问题标题】:State of the stack after goto [closed]goto 后的堆栈状态[关闭]
【发布时间】:2016-06-20 12:52:01
【问题描述】:

在下面的 C 代码中,f 调用 gg 调用 h。请注意h 中的goto,但是:如果a 满足某个条件,它将跳转回f

void h(int a)
{
    if (a > 10)
        goto out;
}

void g(int a, int b)
{
    h(a);
}

void f(int a, int b)
{
    g(a, b);
    return;
out:
    printf("b: %d\n", b);
}

我的问题是:如果goto 被触发,堆栈将如何? gh 会被拆散吗? f 是否仍会打印正确的 b 值? (或者只有在我幸运的情况下才会正确打印?)

(拜托,我不想讨论这是否是一个好的做法,或者是否应该使用它。另外,考虑到实际代码足够复杂,以至于编译器不够聪明,例如优化g out)

[如果重要的话,我可以详细说明我为什么要这样做——我认为不重要]

【问题讨论】:

  • AFAIK 标签必须是功能范围的区域设置。你不能在标准 C 中做到这一点。
  • 您的代码无法为我编译,就像 LP 注释状态一样,goto 是函数范围的语言环境
  • C标准中没有堆栈,你的问题缺乏基础。而且您的代码无效。
  • 从一个函数中的代码跳转到另一个函数中的代码是非常糟糕的。

标签: c stack goto


【解决方案1】:

这将导致标准 C 中未定义的行为。

来自C Language Standard的6.8.6.1/1:

goto 语句中的标识符应命名位于的标签 在封闭函数的某个地方。 goto 语句不能跳转 从具有可变修改的标识符范围之外 在该标识符的范围内键入。

【讨论】:

    【解决方案2】:

    这个问题是无效的,因为它根本不能这样做:你只能在一个函数内goto,而不是函数之间。

    函数之间的跳转可以使用setjmp/longjmp

    【讨论】:

    • 在 C 语言标准中也不需要堆栈。
    • .. setjmp/longjmp 的有趣之处在于他们的设计者很清楚潜在的堆栈问题(在使用它的实现中),因此他们被设计为不 使用与常规函数相同的堆栈。 (查看大量 Stack Overflow 问题,例如 this one。)
    【解决方案3】:

    C 编程中的 goto 语句提供从“goto”到同一函数中的标记语句的无条件跳转。

    标签是单个函数的本地标签,不能在不同函数之间跳转。

    注意 - 在我看来,强烈建议不要使用 goto 语句。

    参考:http://www.tutorialspoint.com/cprogramming/c_goto_statement.htm

    【讨论】:

    • “强烈建议不要使用 goto 语句”是主观的。我只同意“一般”情况。在某些情况下,使用goto 是最简单的方法,例如。 G。错误处理。
    • 我同意@glglgl。 Linux 内核充满了适合的示例
    • goto 在 C 中有它的应用程序。所以不,它并不气馁。这就是 CS 教授告诉学生的。对实际编程有一些见解的教授后来削弱了这种说法。
    • @IshayPeled Linux Kernel 远不是“如何编码”的好例子......我个人的看法。
    • @glglgl 可以同意,但对谁来说是最简单的方法?.. 可能对于懒惰的编码人员... ;)
    【解决方案4】:

    你不能这样做,因为标签是每个特定函数的本地标签。然而,最接近的标准等效函数是 setjmp() 和 longjmp() 函数对。那应该行得通。 :)

    【讨论】:

    • setjmp() 和 longjmp() 不完全等同于恕我直言..
    • 我同意,但是对于初学者的需求,应该就足够了。 :)
    猜你喜欢
    • 2021-06-04
    • 2011-12-08
    • 2018-08-06
    • 2019-10-20
    • 2016-06-19
    • 2015-04-07
    • 2010-12-06
    • 2011-06-13
    • 2016-12-11
    相关资源
    最近更新 更多