问题
Sun Studio 12.1 prints the warning
Warning: The last statement should return a value.
frequently for functions like that:
int f()
{
/* some code that may return */
// if we end up here, something is broken
throw std::runtime_error("Error ...");
}
It is perfectly clear that we do not need a return value at the end of the function. I hesitate to insert something like
// Silence a compiler warning
return 42;
at the end of such a function, since it is dead code anyway. For more complicated return types, it might actually be difficult to construct a 'sensible' bogus value.
What is the recommended way to silence such a warning?
回答1:
Can you reorganize the code in the function in such a way (hopefully more logical as well) that the normal path happens at the end of the function so that a return can be used, and the exceptional path happens earlier, NOT as the last statement?
EDIT: If reorganizing the function really doesn't make sense, you can always just put a dummy return 0;
with a comment. It's better to squelch the warning that way than more globally.
If you really want to quiet the warning permanently, you can use #pragma error_messages (off, wnoretvalue)
but note that the warning really is useful most of the time so I absolutely don't suggest turning it off. You can use the on
version of the pragma to re-enable the warning after the function, but the compiler will still emit the warning if your function is ever inlined. If you put the function in its own source file and use the pragma that should shush the warning relatively safely though, since it can't affect other translation units.
Another really wacky possibility is to switch to g++. Unless you're compiling for SPARC g++ may actually generate better code than Sun studio.
回答2:
I find it a perfect spot for abort()
. You should never end there, according to you, so something like:
UNREACHABLE("message")
which expands into:
#ifdef NDEBUG
#define UNREACHABLE(Message_) abort();
#else
#define UNREACHABLE(Message_) assert(0 && Message_);
#endif
Looks appropriate
回答3:
Since you know the exception will be systematically called, why don't you simply return a 0?
回答4:
Perhaps encapsulate the contents in a do { } while (false);
construct:
int my_function()
{
int result = DEFAULT_VALUE;
do
{
result = /*...*/
// Whatever
if (error)
{
throw std::runtime_error("Error ...");
}
} while (false);
return result;
}
The idea is for normal operation to set the result value then let the execution flow to the end or use a break
to jump to the return
statement.
回答5:
I don't know of a "recommended" way to deal with it, but to answer your question about coping with more complex types, what about:
ComplexType foo()
{
...
throw std::runtime( "Error..." );
return *(ComplexType*)(0);
}
This would then work with any return type. I realise it looks evil, but its there just to silence the warning. As you say, this code will never be executed, and it may even be optimised out.
来源:https://stackoverflow.com/questions/5637561/how-to-silence-the-last-statement-should-return-a-value-warning