这个函数在所有控制path上都有明确的返回值吗?

我有一个Heaviside步骤函数集中于任何数据types,我编码使用:

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

在代码审查中,我的审稿人告诉我,在所有的控制path上都没有明确的回报。 而编译器也不会警告我。 但我不同意; 条件是相互排斥的。 我如何处理这个?

这取决于如何使用模板。 对于一个int ,你很好。

但是 ,如果t是一个值为NaN的IEEE754浮点double精度types,那么t < 1t >= 1都不为true ,所以程序控制到达if块的末尾! 这导致函数返回没有显式值; 其行为是不确定的。

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

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

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

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

以上对任何数据types的“正确”比对<>=理性行为都是正确的。 但是这个:

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

通过检查可以更容易地看到每个案例都被覆盖,并避免了第二次不必要的比较(有些编译器可能没有优化出来)。 代码不仅可以被编译器读取,而且可以被人类读取,包括10年之后。 让人类rest一下,写出更简单的理解。

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

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

想想看。 你想达到什么目的? 必须是这样的:'如果input小于1,则返回0,否则返回1。 你所做的是通过说…增加智力哦,但是这意味着如果t大于或等于1,我返回1.这种不必要的'x暗示y'代表维护者需要额外的思考工作。 如果你认为这是一件好事,我build议你自己做几年的代码维护。

如果是我的评论,我会再说一次。 如果你使用“if”语句,那么你基本上可以在所有分支中做任何你想要的事情。 但在这种情况下,你不会做任何事情。 所有你想要做的是返回0或1取决于是否t <1。 在这些情况下,我认为'?:'声明比if声明更好,更可读。 从而:

return t<1 ? 0 : 1;

我知道一些公司禁止?:运营商,我觉得这是一件可怕的事情。 ?:通常与规格匹配得更好,并且可以使代码更容易阅读(如果小心使用)…