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

Seb*_*ard 62 c++ templates code-coverage return

对于任何数据类型,我都有一个以单位为中心的Heaviside阶跃函数,我用以下编码:

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

在代码审查中,我的审稿人告诉我,所有控制路径都没有明确的回报.编译器也没有警告我.但我不同意; 条件相互排斥.我该如何处理?

Bat*_*eba 230

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

但是,如果t是一个IEEE754浮点double与设置为一个值类型NaN,既不t < 1也不t >= 1true等程序控制到达的端if块!这会导致函数返回而没有显式值; 其行为未定义.

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

这里故事的寓意是决定哪个分支应该是默认的,并将其作为else案例.


Lee*_*ker 13

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

if (t < 1) {
    return 0;
} else if (t >= 1){
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

以上对于任何数据类型都是"正确的",而且对于t具有健全行为<>=.但是这个:

if (t < 1) {
    return 0;
}
return 1;
Run Code Online (Sandbox Code Playgroud)

通过检查更容易看出每个案例都被覆盖,并且完全避免了第二个不需要的比较(某些编译器可能没有优化).代码不仅由编译器读取,而且由人类读取,包括10年后的人.给人类一个休息时间,并为他们的理解更简单地写作.

  • 我知道你想说的是什么(有一个upvote),但这里有一个暗示IEEE754类型不是"理智".这是你的意思吗?此外,我很想看到编译器确实优化第二次条件检查的示例. (2认同)

Ber*_*ril 8

如前所述,一些特殊的号码既可以是<>=,让您的检阅简直是正确的.

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

想一想.你想要实现什么目标?必须是这样的:'如果输入小于1则返回0,否则返回1.你所做的是说...哦,加智力,但是那意味着我返回1,如果t是大于或等于1,这种不必要的"X意味着Y"被要求代表维护者的额外的工作思考.如果您认为这是一件好事,我建议您自己进行几年的代码维护.

如果是我的评论,我会再说一遍.如果您使用'if'语句,那么您基本上可以在所有分支中执行任何操作.但在这种情况下,你不做"任何事情".您要做的就是返回0或1,具体取决于是否t <1.在这种情况下,我认为":"语句是很多比更好,更可读if的语句.从而:

return t<1 ? 0 : 1;

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

  • 我更喜欢`return!(t <1);`或`return t> = 1;`取决于哪一个是"全部捕获"的情况. (2认同)