我从Eclipse得到的错误是“没有返回,函数返回非void”。我添加了默认:case以查看它是否会带走错误,但没有bean。我认为返回一个rvalue是可以的,因为它是按值复制到堆栈上的,因此当getLogLevelName()的局部变量超出范围时,就会存在字符串的副本。确实,调用代码有效,但错误对我来说很神秘。
std::string bmd2::Logger::getLogLevelName(bmd2::Logger::LogLevel logLevel) throw ()
{
switch (logLevel)
{
case bmd2::Logger::LogLevel::LOG_ERROR:
return std::string ("ERROR");
break;
case bmd2::Logger::LogLevel::LOG_WARNING:
return std::string ("WARNING");
break;
case bmd2::Logger::LogLevel::LOG_INFO:
return std::string ("INFO");
break;
case bmd2::Logger::LogLevel::LOG_DEBUG:
default:
return std::string ("DEBUG");
break;
}
}
答案 0 :(得分:6)
Eclipse将此报告为错误,因为它使用的任何C ++分析工具/库都没有推断出switch语句中的default
情况实际上是函数的结尾。即使Eclipse另有说法,这应该表现得非常好。也许安抚Eclipse的更好方法是在switch语句之后放置默认的return语句。
std::string bmd2::Logger::getLogLevelName(bmd2::Logger::LogLevel logLevel) throw ()
{
switch (logLevel)
{
case bmd2::Logger::LogLevel::LOG_ERROR:
return std::string ("ERROR");
case bmd2::Logger::LogLevel::LOG_WARNING:
return std::string ("WARNING");
case bmd2::Logger::LogLevel::LOG_INFO:
return std::string ("INFO");
case bmd2::Logger::LogLevel::LOG_DEBUG:
default:
// We will return the default value after the switch statement.
break;
}
// Return default value.
return std::string ("DEBUG");
}
答案 1 :(得分:0)
您收到此错误是因为您的编译器(Eclipse)无法在return
范围内看到switch
- 语句。你可以添加
return std::string("CAN-BE-ANY-THING"); // this line will never be called though
在函数结束时摆脱错误。
答案 2 :(得分:0)
在C ++中,编写一个声明为返回值但从未实际执行过的函数是完全合法的。只有在运行时执行实际上从这样的函数返回而不返回值时才会出现问题。
// this program is perfectly legal and well behaved; just don't ever call foo()
int foo() {}
int main() { return 0; }
但程序员希望编译器帮助他们生成正确且表现良好的程序,因此编译器会尝试弄清楚程序何时可能会做坏事并告诉程序员它们。问题是C ++定义了“坏事”,如果它们确实可能发生,那么在编译时就能完美地解决这个问题,例如解决停止问题。
显然编译器不会这样做,所以在尝试帮助程序员时,编译器有时会出错。希望编译器在大多数情况下能够很好地处理大多数实际代码的情况,但是不可避免地会出现编译器无法处理的情况,从而导致误报(编译器会警告无法实际发生的问题)或假阴性(编译器无法警告可能发生的问题)。
您有两个基本选择:要么告诉编译器停止尝试以产生此消息的特定方式帮助您(通过禁用此警告),或者您可以更改代码以便编译器不是非常正确的分析仍然能够发现它总是返回一个值。
除了C ++以外的语言采取了其他方法,例如简单地将非法返回值以使简单分析可以看到返回值是非法的。例如,C#明确地采用该路由,以便编译器可以检查它并完全正确。