为什么编译器声称此类方法没有回报值



我从eclipse遇到的错误是"无返回,函数返回非void"。我添加了默认值:查看它是否会消除错误,但没有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;
  }
}

eclipse将其报告为一个错误,因为它使用的任何C 分析工具/库都不是在确定开关插件中的default情况有效地是函数的末尾。即使Eclipse否则,这也应该表现得很好。安抚日食的更好方法可能是将默认返回语句放在开关语句之后。

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");
}

您遇到了此错误,因为您的编译器(Eclipse)看不到switch范围中的return统计。您可以添加

return std::string("CAN-BE-ANY-THING");  // this line will never be called though

在功能结束时摆脱错误。

在C 中,编写声明为返回值但从未实际使用的函数是完全合法的。仅当运行时执行实际上从该功能返回而不返回值时,就会发生问题。

// this program is perfectly legal and well behaved; just don't ever call foo()
int foo() {}
int main() { return 0; }

但程序员希望编译器帮助他们制作正确且行为良好的程序,因此编译器试图弄清程序何时可能会做坏事并告诉程序员。问题在于,C 定义了"坏事",因此,如果确实可以解决,则可以在编译时间完美弄清楚,例如解决停止问题。

显然,编译器不会做到这一点,因此在尝试帮助程序员时,有时编译器会弄错问题。希望编译器在大多数情况下都能很好地处理真实代码的大多数情况,但是不可避免地会有编译器无法处理的情况,因此会导致假阳性(编译器警告的问题确实不会发生))或假否定(编译器未能警告可能发生的问题)。

您有两个基本选择:要么告诉编译器停止尝试以产生此消息的特定方式帮助您(通过禁用此警告),要么可以更改代码,以便编译器的不正确分析仍然能够弄清楚它总是返回一个值。


C 以外的其他语言采用了其他方法,例如简单地使无法返回值的违法行为以一种简单的分析可以看到返回的方式。例如,C#明确采用该路线,以便编译器可以检查并完全正确。

最新更新