Why does the compiler claim this class method has no return value?

The error I get from Eclipse is "No return, in function returning non-void." I added the default: case to see if it'd take away the error, but no beans. I thought it'd be okay to return an rvalue because it'd be copied-by-value onto the stack and thus a copy of the string would exist when the local variables of getLogLevelName() go out of scope. Indeed, the calling code works, but the error is mysterious to me.

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

Answers


Eclipse is reporting this as an error because whatever C++ analysis tool/library it's using is it not deducing that the default case in the switch-statement is effectively the end of the function. This should behave perfectly fine even though Eclipse says otherwise. Perhaps a better way to pacify Eclipse would be to put the default return statement after the switch statement.

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

You got this error because your compiler (Eclipse) can not see the return-statement in the switch scope. You can add

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

at the end of the function to get rid of the error.


In C++ it's perfectly legal to write a function which is declared to return a value but never actually does. A problem occurs only if execution at runtime actually returns from such a function without returning a value.

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

int main() { return 0; }

But programmers want compilers to help them produce correct and well behaved programs, and so compilers try to figure out when a program could possibly do bad things and tell the programmer about them. The problem is that C++ defines 'bad things' such that perfectly figuring out at compile time if they really can happen requires, for example, solving the halting problem.

Obviously a compiler isn't going to do that, so in trying to help the programmer sometimes the compiler is going to get things wrong. Hopefully the compiler handles most cases of real code well most of the time, but there will inevitably be cases the compiler doesn't handle and which therefore result in a false positive (where the compiler warns of a problem that can't really happen) or false negative (where the compiler fails to warn about a problem that can happen).

You have two basic choices: Either tell the compiler to stop trying to help you in the particular way that produces this message (by disabling this warning), or you can change the code so that the compiler's not-quite-correct analysis is still able to figure out that it always returns a value.


Languages other than C++ have taken other approaches, such as simply making it illegal to fail to return a value in such a way that a simple analysis can see the return. C#, for example, takes that route explicitly so that the compiler can check it and be completely correct.


Need Your Help

How to assign .net membership roles to individual database records

asp.net asp.net-membership

I'm developing a system where we want to restrict the availability of information displayed to users based on their roles.

How to read images with different size in a TFRecord file

python deep-learning tensorflow

I have created a dataset and saved it into a TFRecord file. The thing is the pictures have different size, so I want to save the size as well with the images. So I used the TFRecordWriter and defin...