【问题标题】:Using Goto function across different functions跨不同功能使用 Goto 功能
【发布时间】:2013-06-28 04:30:36
【问题描述】:

如何在不同的功能中使用goto?例如:

int main() {
    // ....
    REACH:
    // ....
}
    
void function() {
    goto REACH;
}

【问题讨论】:

  • 你不应该使用 goto xkcd.com/292
  • 改用setjmp
  • 问题:你到底为什么要这样做?当然还有更好的方法。
  • @Ben 不要一概而论。 goto总是被认为是一种不好的做法。 gotoC 中是very useful,当您需要优雅地清理并退出函数时。您可以在 Linux 内核和许多其他大型项目中看到许多 goto 指令。
  • 也有利于打破多个嵌套循环。

标签: c++ c goto


【解决方案1】:

你不能在标准 C++ 中。 C++ 语言标准 $6.6.4/1 起

goto 语句无条件地将控制转移到由标识符标记的语句。标识符应为位于当前函数中的标签 (6.1)。

...或在标准 C 中。从 C 语言标准的 $6.8.6.1/1 起

goto 语句中的标识符应命名位于封闭区域某处的标签 功能。 goto 语句不应从具有以下内容的标识符范围之外跳转 在该标识符范围内进行可变修改的类型。

【讨论】:

    【解决方案2】:

    你不能在标准 C 中;标签是单个函数的本地标签。

    最接近的等效标准是setjmp()longjmp() 函数对。

    GCC 有 extensions 来更普遍地支持标签。

    【讨论】:

      【解决方案3】:

      对于 gcc:

      #include <iostream>
      
      void func(void* target){
          std::cout << "func" <<std::endl;
          goto *target;
      }
      
      
      int main() {
          void* target;
          auto flag = true;
      l:
          std::cout << "label" <<std::endl;
          target = &&l;
          if (flag) {
              flag = false;
              func(target);
        }
      }
      

      请注意,这可能是未定义的行为

      【讨论】:

      【解决方案4】:

      你不能。想想这个。有一个函数 A 递归调用另一个函数 B,而 B 又调用 A。现在,假设您将 goto 语句从 A 放到 B。现在的问题是您要转到 A 的哪个实例,哪个未定义.此外,如果没有定义 A 的先前实例,则您会遇到更大的问题,即函数中没有标签之前存在的初始化变量。

      #include "bits/stdc++.h"
      int i=0;
      A(){
      run:
          B();
      }
      B(){
      if(i==10)
          goto run;
      i++;
      A();
      }
      

      【讨论】:

      • 好点。这正是函数的问题。从这个意义上说,我们无法控制堆栈。我们应该能够恢复它的一部分和/或将某些位置存储在我们想要恢复到的堆栈中。有setjmp()longjmp(),但是当涉及到“堆栈”变量时,它们很慢并且会带来麻烦。问题是为了方便,我们放弃了非常有用的功能。整个范式都有缺陷。
      猜你喜欢
      • 1970-01-01
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 2021-04-16
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      相关资源
      最近更新 更多