GOTO 还是不 GOTO?

新手上路,请多包涵

目前我正在研究一个大量使用 goto 语句的项目。 goto 语句的主要目的是在例程中有一个清理部分,而不是多个返回语句。如下所示:

 BOOL foo()
{
   BOOL bRetVal = FALSE;
   int *p = NULL;

   p = new int;
   if (p == NULL)
   {
     cout<<" OOM \n";
     goto Exit;
   }

   // Lot of code...

Exit:
   if(p)
   {
     delete p;
     p = NULL;
   }
   return bRetVal;
}

这使得它更容易,因为我们可以在代码的一个部分(即 Exit 标签之后)跟踪我们的清理代码。

但是,我已经阅读了很多地方,使用 goto 语句是不好的做法。

目前我正在阅读 _Code Complete_ 这本书,它说我们需要使用接近其声明的变量。如果我们使用 goto,那么我们需要在第一次使用 goto 之前声明/初始化所有变量,否则编译器将给出错误,即 goto 语句跳过了 xx 变量的初始化。

哪种方式是正确的?


来自斯科特的评论:

看起来使用 goto 从一个部分跳转到另一个部分是不好的,因为它使代码难以阅读和理解。

但是,如果我们只使用 goto 前进并转到一个标签,那么它应该没问题(?)。

原文由 anand 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 825
2 个回答

我不确定清理代码是什么意思,但在 C++ 中有一个名为“ _资源获取就是初始化_”的概念,你的析构函数应该负责清理内容。

(注意,在 C# 和 Java 中,这通常通过 try/finally 来解决)

有关更多信息,请查看此页面: http ://www.research.att.com/~bs/bs_faq2.html#finally

编辑:让我澄清一下。

考虑以下代码:

 void MyMethod()
{
    MyClass *myInstance = new MyClass("myParameter");
    /* Your code here */
    delete myInstance;
}

问题:如果函数有多个退出会发生什么?您必须跟踪每个出口并在所有可能的出口处删除您的对象!否则,您将有内存泄漏和僵尸资源,对吗?

解决方案:改用对象引用,因为当控件离开范围时它们会自动清理。

 void MyMethod()
{
    MyClass myInstance("myParameter");
    /* Your code here */
    /* You don't need delete - myInstance will be destructed and deleted
     * automatically on function exit */
}

哦,是的,并使用 std::unique_ptr 或类似的东西,因为上面的例子显然是不完美的。

原文由 Tamas Czinege 发布,翻译遵循 CC BY-SA 3.0 许可协议

我在 C++ 代码中使用 goto 的唯一两个原因是:

  • 打破 2 级以上的嵌套循环
  • 像这样的复杂流程(我的程序中的评论):
   /* Analysis algorithm:

  1.  if classData [exporter] [classDef with name 'className'] exists, return it,
      else
  2.    if project/target_codename/temp/classmeta/className.xml exist, parse it and go back to 1 as it will succeed.
  3.    if that file don't exists, generate it via haxe -xml, and go back to 1 as it will succeed.

*/

这里为了代码可读性,在这个注释之后,我定义了step1标签,并在第2步和第3步中使用了它。实际上,在60多个源文件中,只有这种情况和嵌套的一个4层是我使用goto的地方。只有两个地方。

原文由 Петър Петров 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏