C/ c++(其他语言?)条件提前返回良好的代码实践

C/C++ (Other Languages Too?) Conditional Early Return Good Code Practice

本文关键字:返回 代码 条件 c++ 其他 语言      更新时间:2023-10-16

最近,我在审查我维护的一些代码时,注意到一种与我习惯的做法不同的做法。因此,我想知道在函数中执行早期返回时使用哪种方法。

下面是一些例子:

版本1:

int MyFunction(int* ptr)
{
  if(!ptr) {  // oh no, NULL pointer!
    return -1;  // what was the caller doing? :(
  }
  // other code goes here to do work on the pointer
  // ...
  return 0;  // we did it!
}
版本2:

int MyFunction(int* ptr)
{
  if(!ptr) {  // oh no, NULL pointer!
    return -1;  // what was the caller doing? :(
  } else {  // explicitly show that this only gets call when if statement fails
    // other code goes here to do work on the pointer
    // ...
    return 0;  // hooray!
  }
}

因此,我想知道对于那些忍受(并幸存下来)许多代码审查的人来说,哪一个被认为是"最佳实践"。我知道每个都能有效地做同样的事情,但是"else"在可读性和清晰度方面增加了多少吗?谢谢你的帮助。

如果else子句很短,最多只有几行代码,那么else只会增加清晰度。如果你想要检查几个初始条件,那么源代码很快就会变得混乱。

我唯一会使用else的情况是,它是一个带有小else的小函数,意味着少于10行源代码,并且没有其他初始检查要做。

在某些情况下,我使用了单个循环,以便一系列初始检查可以使用break离开。

do {
 ...
 } while (0);

我讨厌使用goto,因为它实际上肯定会让至少一个真正的goto少编程的信仰者奋起反抗。

这很大程度上取决于您组织的任何代码标准。我倾向于极简主义,所以我使用你提供的第一个版本,不带else。

我还可以在一个较小的函数中做如下操作,比如少于20或30行:

int MyFunction(int* ptr)
{
  int iRetStatus = -1;  // we have an error condition
  if (ptr) {  // good pointer
      // stuff to do in this function
      iRetStatus = 0;
  }
  return iRetStatus;  // we did it!
}

函数体中return的唯一问题是,有时人们扫描函数时没有意识到有一个return。在小函数中,所有内容都可以在一个屏幕上看到,因此错过返回的可能性非常小。然而,对于大型函数,中间的返回值可能会被忽略,尤其是那些经历了几个维护周期,并且在其中投入了大量繁琐和工作的大型复杂函数。