多个return语句或“goto end”;

时间:2011-05-20 15:48:05

标签: c++ coding-style return goto

什么是更好的风格/可读性?

我有一个循环读取输入并根据输入执行不同的操作,当发生错误时,我需要一个简单的return;。例如:

while( get_input() )
{
    if( input == "somethingcool" )
    {
        if( !process_somethingcool() )
            return; // <-- a couple of these
    }
    //...
    else // bad input, error handling is fancier than this, but irrelevant to the question
        return;
}
return;

那么我应该用return;替换单个goto end;并在上面的示例中的最后一个返回的正上方放置标签end:吗?我不需要“使用RAII”,因为if块中没有分配任何内容。除了风格/可读性/性能之外,这两种方式在所有意义上都是相同的吗?

我认为性能是相同的,但只是为了确定:是吗?

12 个答案:

答案 0 :(得分:4)

对于C,goto是合理的(它在Linux内核中广泛使用),因为您可以通过单点返回来增强可读性。

对于C ++,因为你有可能抛出异常,你隐含地有多个返回点,所以你应该总是使用多次返回的RAII模型。

答案 1 :(得分:3)

就个人而言,我喜欢尽量减少任何块的内容。一条线,呼唤另一个功能是理想的(在Bob Martin的清洁代码之后)。

我会选择你没有提出的选项:

while(get_input()) {
    if(!process_input(input)) {
         break;
    }
}

其中process_input将选择适当的process_...函数,返回返回的内容,如果输入错误,则返回false。

答案 2 :(得分:3)

你想开始宗教战争吗?

说真的,有时候goto是最好的选择。二十年来,我已经看过3或4左右。多次回归并不一定是邪恶的,但如果你不得不重复大量的清理代码,那么它们就会变得非常混乱。

通常,您可以重构代码以使这种选择变得不必要。如果没有看到你的代码,很难提出具体的建议,但也许是这样的:

void f()
{
   bool bDone=false;
   while (!bDone && get_input())
   {
      if (input == "cool")
      {
         process_cool();
         bDone = true;
      }
      else if (input == "unfinished")
      {
         process_something();
      }
      else
      {
          // error
          bDone = true;
      }
   }
}

重构的一个重要帮助是确保循环中没有几十行。如果您有大量工作要做,请将其分解为函数并从while循环中调用少量函数。

请记住,单个函数应该只做一件事。

强烈建议使用另一种方法是使用异常来处理错误情况,但如果刚刚完成处理则使用异常是不好的方式,因此这可能无法完全解决您的问题。

如果您仍然感到困惑,请考虑发布更实际的代码块,我们可能会建议如何最好地处理事情。

祝你好运!

答案 3 :(得分:2)

当您想要返回时,只需返回。 C ++语言可以处理它,它是编写代码的最直观方式。

在某些语言中,必须在使用站点进行清理,因此将“清理”阶段集中在您“转到”的单个块中可能是个好主意。在C中,这个成语很常见。

在C ++中,当资源超出范围时,资源会在析构函数中自行清除 。所以在使用网站上,没有需要完成,而最容易,最干净,最不容易出错的解决方案就是只有多个返回语句。

答案 4 :(得分:1)

样式和可读性会导致我使用异常来处理错误情况。您的调用者如何知道您的方法是否被正确调用?

那说:goto不应该用于此; return是更好的选择。如果你需要在例行程序结束时做任何事情,无论它退出的原因是什么 - 那么你应该抛出异常并使用catch块。

答案 5 :(得分:1)

return通常优先于goto;通常,标签的批评者无法提出任何实际的论据来支持他们的教条。 1

但是,你的情况更明确:你为什么选择goto?两个解决方案都是等效的,只是goto要求你在函数结束之前写end:,占用空间并且无缘无故地看起来很丑。

因此,在提出的两个选项中,我建议使用return s。也就是说,我还建议认真考虑回答这个问题的其他建议(例外情况,并限制条件的“嵌套性”)。


1 或者,如果他们这样做,通常会出现“goto使你的对象挂起”,这是不正确的(按照{{3中的6.6 / 2} }})。 goto 不会破坏RAII模型

答案 6 :(得分:1)

多个return语句实际上是好的样式,并且几乎总是产生比尝试单个返回点更清晰的代码。在C ++中,gotos是无用的(除了他们的其他问题),他们不能跳过初始化,这可能会迫使你把东西从他们的使用点初始化,这也是糟糕的风格。

答案 7 :(得分:0)

goto End;很好,部分原因在于可读性,但也因为如果你以后意识到在关闭函数,释放内存或释放资源之前需要发生的事情,你可以集中处理这个过程复制粘贴它。

答案 8 :(得分:0)

实际上,不建议使用goto。它会在代码的可读性方面产生问题。更好地使用break;语句,您希望离开循环并返回代码末尾。这是标准程序。

while( get_input() )
{
    if( input == "somethingcool" )
    {
        if( !process_somethingcool() )
            break; // <-- a couple of these
    }
    //...
    else // bad input, error handling is fancier than this, but irrelevant to the question
        break; //although its better if you handle it somehow here.
}
return;

答案 9 :(得分:0)

为什么不使用“guard子句”(通过反转逻辑)而不是嵌套ifs来构造代码。那么使用goto的整个问题就变得毫无意义了。

while( get_input() )
{
    if( input != "somethingcool" )
    {
        return; //handle error
    }
    if( !process_somethingcool() )
        return; //handle error
    }
}
return; //success

答案 10 :(得分:0)

都不是。您应该将代码重构为可读的内容 并且可维护。我见过的每一个案例(我见过很多) 程序员需要goto的情况,以及大多数情况 他需要多次退货(以及所有的情况) 返回已嵌套在循环中)将更好地解决 将代码重构为单独的,更简单的函数,每个函数 在函数结束时返回一次。 (多 对于非常简单的函数,返回有时是合理的;例如 如果函数中唯一的语句是,我将使用它们 一个switch,每个案例都以return结尾。)

答案 11 :(得分:-1)

恕我直言使用多次返回并且不使用goto。那些使用goto的人也会把狗放在火上。