此函数是否在所有控制路径上都有明确的 return 值?

Does this function have explicit return values on all control paths?

我有一个 Heaviside step function 以统一为中心的任何数据类型,我使用以下方式对其进行编码:

template <typename T>
int h1(const T& t){
   if (t < 1){
       return 0;
   } else if (t >= 1){
       return 1;
   }
}

在代码审查中,我的审查者告诉我,所有控制路径上都没有明确的 return。而且编译器也不警告我。但我不同意;这些条件是相互排斥的。我该如何处理?

这取决于模板的使用方式。对于 int,你很好。

但是,如果t是一个IEEE754浮点double类型,值设置为NaN,则两者都不是t < 1 t >= 1 也不是 true,因此程序控制到达 if 块的末尾!这会导致函数 return 没有显式值;其行为未定义。

(在更一般的情况下,T 以不涵盖所有可能性的方式重载 <>= 运算符,程序控制将到达if 块没有显式 return。)

这里故事的寓意是决定哪个分支应该是默认分支,并使那个分支成为 else 案例。

仅仅因为代码是正确的,并不意味着它不能更好。正确执行是质量的第一步,而不是最后一步。

if (t < 1) {
    return 0;
} else if (t >= 1){
    return 1;
}

以上是 "correct" 的 t 的任何数据类型,而不是 <>= 的正常行为。但是这个:

if (t < 1) {
    return 0;
}
return 1;

通过检查更容易看出每个案例都已涵盖,并且完全避免了第二次不必要的比较(某些编译器可能没有优化)。代码不仅会被编译器阅读,还会被人类阅读,包括 10 年后的你。让人类休息一下,为了他们的理解也写得更简单。

如前所述,一些特殊数字可以是 <>=,因此您的评论者完全正确。

问题是:最初是什么让您想要这样编写代码?为什么你甚至考虑让你自己和其他人(需要维护你的代码的人)生活如此艰难?事实上,您足够聪明地推断出 <>= 应该涵盖所有情况,但这并不意味着您必须使代码变得比必要的更复杂。物理适用于代码也适用:让事情尽可能简单,但不要更简单(我相信爱因斯坦这么说)。

想一想。你想达到什么目的?必须是这样的: 'Return 0 if the input is less than 1, return 1 otherwise.' 你所做的是通过说...来增加智能...哦但这意味着我 return 1 如果 t 大于或等于 1。这种不必要的 'x implies y' 代表维护者需要额外的思考工作。如果您认为这是一件好事,我建议您自己进行几年的代码维护。

如果这是我的评论,我会再发表评论。如果你使用 'if' 语句,那么你基本上可以在所有分支中做任何你想做的事情。但在这种情况下,您不会执行 'anything'。您要做的就是 return 0 或 1,具体取决于 t<1 与否。在那些情况下,我认为 '?:' 语句 if 语句更好 并且更易读。因此:

return t<1 ? 0 : 1;

我知道 ?: 运算符在某些公司是被禁止的,我发现这样做很糟糕。 ?: 通常与规范匹配得更好,它可以使代码更易于阅读(如果小心使用)...