【问题标题】:What is an indirect goto statement?什么是间接 goto 语句?
【发布时间】:2019-05-26 19:43:21
【问题描述】:

在 Clang API 中,有一个 GotoStmt 和一个 IndirectGotoStmt。关于这两种 goto 语句之间的区别的解释很少。我知道goto label; 声明是什么。但什么是间接 goto 语句?我想知道在 C/C++ 代码的上下文中是什么,而不仅仅是 Clang。 间接 goto 语句在语法上意味着什么?能否提供代码示例?

编辑:以下问题很有趣。

Can you make a computed goto in C++

【问题讨论】:

  • 您在询问实施细节。就 C++ 而言,这些都无关紧要。
  • 我的猜测是,这是指向变量中包含的位置的 goto 语句,它是 gcc 扩展,clang 旨在与 gcc 兼容。
  • 或许类似于switch case语句?但是 Clang API 已经为该 [SwitchCase ][3] 提供了一个特定的类。 [3]:http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html
  • @Galaxy 请添加链接问题的有趣之处。这和你的问题有关系吗?
  • @JL2210 该链接问题是相关问题。在那个问题中,我们还可以找到有关 GCC 的标签扩展地址以及如何使用它的信息。阅读我的问题的人也希望阅读该问题,以详细了解有关此编码结构的更多信息。链接的问题往往以某种方式相关。在这里,我们看到了清晰的关系,因为这两个问题都是关于同一个编码结构。

标签: c++ c llvm-clang goto


【解决方案1】:

有一个 GNU 扩展允许获取标签的地址,将其存储以供以后使用,然后 goto 该地址在以后使用。有关详细信息,请参阅https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html。示例:

    void *ptr;

    if(...)
        ptr = &&foo;
    else
        ptr = &&bar;

    /* ... */
    goto *ptr;

foo:
    /* ... */

bar:
    /* ... */

Clang 也支持这一点,因为它旨在与 GCC 兼容。

例如,在实现状态机时,可能会用到上述内容。

【讨论】:

  • && 运算符是什么?这就是你获取标签地址的方式吗?好像是取地址的地址,没有意义。我以前从未遇到过这种语法。
  • @CareyGregory 是的,还有其他方法可以实现此功能,但他们可能会更多地使用一两条汇编指令。请记住,并非每台计算机都是具有大量备用内存和周期的台式机。 GCC 也用于微控制器
  • 不清楚间接goto 是否会处理析构函数等。手册说你不应该在函数之间传递标签,但即使在单个函数中,也可能有大括号组在goto 和变量通常会被破坏但不能被这种机制破坏的标签之间。使用它时要格外小心。它被从 Fortran 中删除是因为它引起了麻烦(尽管它可以在函数之间使用);大多数人在 70 年代就停止在 Fortran 中使用它,因为它会导致代码无法维护。在新代码中使用它不是一个好主意。
  • @CareyGregory No piece of code using a construct like that would ever survive a code review with me - 标签作为值扩展被广泛用于手动优化的跳转表glibc printf
  • @JonathanLeffler Clang 拒绝间接跳过非平凡的析构函数。 GCC 只是忽略了这个事实,根本没有调用析构函数。 godbolt.org/z/4aXAgZ.
猜你喜欢
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多