在函数中从一个点返回

3

可能是重复问题:
一个函数应该只有一个返回语句吗?

你好,

gcc 4.4.4 c89

在一个函数中仅从一个点返回是否是良好的编程实践。

下面是我编写的一个函数。但是,我有两个可能的返回点。

这种风格好吗?

static int init_data(struct timeout_data_t *timeout_data)
{
    if(timeout_data == NULL) {
        fprintf(stderr, " [ %s ] [ %d ]\n",
            __func__, __LINE__);
        return FALSE;
    }

    /* Assign data */
    timeout_data->seconds = 3;
    timeout_data->func_ptr = timeout_cb;

    return TRUE;
}

3
这是一个与广受欢迎的“函数是否应该只有一个返回语句?”问题完全相同的副本。 - James McNellis
10个回答

11
如果它有助于可读性,那就没有什么问题。就我个人而言,我经常编写这种代码。

7

这是一个没有被接受答案的持续宗教式辩论。在争论的双方中,有很多人对此持有强烈的看法。

个人认为这并没有什么问题,但最好的方法是遵循您团队的样式指南(如果有的话),如果没有,就询问一下。如果有人感到惊恐,那么坚持单一返回点可能更为友善。


4

我曾经遇到过一些经理,他们为了“易读性”而坚持使用1个换行符的规则,尽管在某些情况下,即使不使用换行符,也会更易读。

总的来说……如果发薪人告诉你只能使用一个换行符,请按照要求去做。最好的方法是

type myfunc(params) {
    type result = defaultValue;
    // actual function here, word for word
    // replace "return $1" with "result = $1"

    return result;
}

这是他们认为的一种有效的做法,遵守你的1次退货政策将会得到赞赏。当然,你知道这样做并没有增加任何可读性,因为你所做的只是用“result =”替换了语法高亮显示的“return”。但是你让你的老板开心了,毕竟归根结底,开发工作就是为了让老板满意,对吧? :-)


+1:我的情况完全一样(我们的编码标准强制执行这些规则) - INS
1
这是一种有点错误的建议。Return语句会停止其后的语句执行,而简单的赋值语句并不会如此。因此它并不是一个完美的解决方案。 - unwind
1
这不仅仅关乎可读性——有多个返回点存在更重要的可靠性和维护问题。 - Paul R
@Paul 如果你的函数非常大,以至于多个返回点不是立即明显的,那么就会有更大的维护问题。 - corsiKa

2
你把问题标记为“C”,这会有所不同。
在C语言中,你可能会编写如下代码:
open file
process data
close file

如果在处理数据部分中间加入返回,则很可能会跳过必要的清理工作,因此具有多个返回点可能被认为是不良实践,因为这很容易出错。

如果使用C ++,最好的做法是让析构函数处理清理工作,因此这个建议在C++中已经过时了,不太可能出现潜在问题。


2
在纯C中,我认为在函数顶部进行错误检查/参数验证并使用return(甚至可能在参数验证中有多个返回点)可以产生相当干净的代码。 但是,在此之后,我认为在函数底部具有一个单一的返回是一个好主意。这有助于避免在函数工作中分配的清理问题(例如,内存释放)。

2

如果你在返回错误时有多个出口,那么这并没有什么本质上的问题。立即返回通常比将整个代码块包装在if/else语句中,并在最后设置一些结果标志要更清晰。当你看到"return result;"时,你必须浏览之前的所有代码,以查看如何设置和何时设置结果。更多的移动部件==更少的清晰性。


1

正如Oded和Andrzej Doyle所指出的,这没有任何问题。

在这方面,没有什么黄金法则可言。

编写代码时,首要且最重要的事情是要记住,其他人将不得不阅读它并理解它。也许几个月后你自己也需要重新阅读代码,如果你写得一团糟,那么你会后悔的。

就我个人而言,我总是:

  • 如果代码是新的,则使用项目中其他人正在使用的编码风格。
  • 如果编辑其他人的代码,则使用已经实现的编码风格。
  • 尽量避免进行代码优化(编译器最擅长此项工作)。
  • 保持代码简洁。

1
如果你的函数足够小(10-15行),正如它应该的那样 :), 那么使用单个返回点或多个返回点都无关紧要,两者都同样易读。
问题开始出现在设计不良的大型函数中。在这种情况下,无论是从单个点返回还是从多个点返回,都会进一步复杂化函数,尽管在这种情况下,我更喜欢早期返回和多点返回。

1
通常情况下,在开始实际工作之前,您需要检查多种条件等等,然后你会被引导在代码中进行早期返回。我认为这对于简短的方法来说很好,但当它变得更加复杂时,我建议将代码拆分为一个“设置和检查”方法和一个“真正的工作”方法,并且两者只有一个出口。当然,只要可读性不受影响,就可以有多个返回值(例如在长switch语句中)。

1

尽早失败(并因此返回)是一种非常好的实践。检查之后的所有代码都不会有很多潜在的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接