并不是所有的控制路径在我的bool检查中都返回一个值



我实际上检查了所有参与者,但仍然找不到它缺少返回值的地方。感谢您查看我的代码<3

bool Time::check()
{
if ((month < 1) || (month > 12)) return false;
switch (month)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
lastday = 31;
if ((day <= lastday) && (day > 0)) return true;
else return false;
break;
case 4:case 6:case 9:case 11:
lastday = 30;
if ((day <= lastday) && (day > 0)) return true;
else return false;
break;
case 2:
if ((year % 4) == 0)
{
lastday = 29;
if ((day <= lastday) && (day > 0)) return true;
else return false;
}
else
{
lastday = 28;
if ((day <= lastday) && (day > 0)) return true;
else return false;
}
}
}

最大的问题是:你的编译器不够聪明。当然,从逻辑上讲,编写的函数不可能不返回,但编译器并没有将初步的范围检查与switch捆绑在一起,以实现任何到达switch的代码都将始终匹配其中一种情况。

最简单的解决方案是取消手动范围检查,并由switchdefault情况处理,例如:

bool Time::check()
{
switch (month)
{
// Original cases here
default:          // added
return false; // added
}
}

可以通过避免代码重复来进一步改进代码;区分你的switchcases的唯一是lastvalue。因此,将它们限制在这个范围内,并将公共代码放在switch:之外

bool Time::check()
{
int lastday; // Declared outside the switch so it's available for final test
switch (month)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
lastday = 31;
break;
case 4:case 6:case 9:case 11:
lastday = 30;
break;
case 2:
lastday = year % 4 == 0 ? 29 : 28; // Note: Leap year rules are more complicated than this; look 'em up
break;
default:
return false; // Not a valid month; could do lastday = 0; break; to stick to a single return but that's liable to confuse
}
return day <= lastday && day > 0;
}

编译器试图理解您的代码,但并非总是能够理解所有内容。有类似问题的另一个代码是:

int foo(int x){
if (x <= 1 || x >= 3) return false;
if (x == 2) return true;
}

要么x2,要么x不是2,那么它就是<= 1>= 3。因此,函数总是返回。尽管如此,编译器还是发出警告:

<source>:6:1: error: control reaches end of non-void function [-Werror=return-type]

考虑一下这个模糊的版本,它可能与编译器用于分析的内容类似:

int foo(int x){
if (some_condition) return false;
if (some_other_condition) return true;
}

如果some_conditionsome_other_condition都不是true,则函数不会返回,这是未定义的行为。

长话短说,编译器很聪明,但还不够聪明,无法看到您正在覆盖month的所有可能值。要修复它,请删除初始if,并添加一个default大小写。或者更确切地说,将所有情况下常见的一切都转移到交换机之外:

bool Time::check()
{
int lastday = 0;
switch (month)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
lastday = 31;
case 4:case 6:case 9:case 11:
lastday = 30;
break;
case 2:
if ((year % 4) == 0)
{
lastday = 29;
}
else
{
lastday = 28;
}
default: lastday = -1;
}
return ((day <= lastday) && (day > 0));
}

我建议将查找每月天数的逻辑从函数check中移除。你可以使用一个数组:

int days(int month,int year)
{
int days_per_month[] = {31,28,31,30,31,30,31,31,30,30,31,30,31};
return days_per_month[month-1] + (month==2 && year%4==0);
}

最新更新