Why is this an issue?
Every call to a function with a non-void return type is expected to return some value. Including a return path in a non-void function that does not
explicitly return a value results in undefined behavior.
Conversely, every call to a function with a void return type is expected to not return any value. Returning a value from a void function probably
indicates a programming error.
Noncompliant code example
int my_func (int a)
{
if (a > 100)
{
return; // Noncompliant
}
if (a > 80)
{
throw new Exception(); // Compliant
}
// Noncompliant
}
Compliant solution
int my_func (int a)
{
if (a > 100)
{
return 12;
}
if (a > 80)
{
throw new Exception();
}
return a;
}
Exceptions
This rule doesn’t raise an exception when the return
statement for a void
function, is itself a void
expression.
void foo() {
// Do stuff ...
}
void bar() {
return foo();
}
Furthermore, the issue is not raised for the coroutines, introduced in {{cpp20}}, that always declare coroutine object as a return type, but
returned object is implicitly created by compiler. The coroutine body itself may never contains return
statement (the use of it is
disallowed), and co_return
is used for coroutine that returns a value (define return_value
in promise-type).
Resources
- {rule:cpp:S6369} - Coroutine should have co_return on each execution path or provide return_void
- MISRA C:2004, 16.8 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
- MISRA C++:2008, 8-4-3 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
- MISRA C:2012, 17.4 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
- MITRE, CWE-394 - Unexpected Status Code or Return Value
- CERT, MSC37-C. - Ensure that control never reaches the end of a non-void function
- CERT, MSC52-CPP. - Value-returning functions must return a value from all exit paths
- CERT, MSC53-CPP. - Do not return from a function declared [[noreturn]]