Bug 55767 - flowing off end of function which returns a value isn't treated as an error by default
Summary: flowing off end of function which returns a value isn't treated as an error b...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.3
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2012-12-20 19:15 UTC by Rui Maciel
Modified: 2024-01-12 00:53 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rui Maciel 2012-12-20 19:15:56 UTC
Consider the following code:

<code>
#include <iostream>

int& foo() {}

int main(void)
{
    foo() = 1 + 1;

    std::cout << foo() << std::endl;

    return 0;
}
</code>

Function foo() returns a value, which is a reference to an int, and in spite of no return statement being provided, g++ compiles the above code without throwing any error.  It does throw a warning when compiling with -Wall.

In the C++ standard, in section 6.6.3, it is stated that "A return statement without an expression can be used only in functions that do not return a value".  It is also stated that "Flowing off the end of a function is equivalent to a return with no value", following that "this results in undefined behavior in a value-returning function."

In spite of this behavior being explicitly left in the standard as "undefined behavior", this loophole contradicts other behavior specifications made by the standard.  Even then, its definition of "permissible undefined behavior" the standard also includes "terminating a translation or execution (with the issuance of a diagnostic message)".

As the example above shows, by ignoring the situation completely without even issuing any diagnostic message, g++ is opening the doors to results which aren't easily explained or expected, which constitutes a problem.

I've noticed that clang++ throws a warning by default for this particular example, and I've read reports that MSVC++ 2010 actually throws a compiler error, which is the best possible result for this kind of problem.

It would be nice if g++ handled functions that flowed off the end as errors instead of silently accepting them by default.
Comment 1 Jonathan Wakely 2012-12-20 19:34:55 UTC
It's not always possible to make it a hard error and refuse to compile the code. The function might call a function that never returns (but isn't marked with a noreturn attribute) or might be of the form:

  int& f(bool b) {
    if (b) {
      static int i;
      return i;
    }
  }

If this is never called with a false argument there's no problem. If it's never called at all there's no problem.

Unless GCC's flow analysis is improved I think the most you can hope for is enabling -Wreturn-type by default.

I use -Werror=return-type, the warning's there already, use it if you want it.
Comment 2 Eric Gallager 2017-09-27 01:43:19 UTC
Yup, -Werror=return-type makes gcc reject the reporter's example:

$ /usr/local/bin/g++ -c -Wall -Wextra -pedantic -Werror=return-type 55767.cc
55767.cc: In function ‘int& foo()’:
55767.cc:3:13: error: no return statement in function returning non-void [-Werror=return-type]
 int& foo() {}
             ^
cc1plus: some warnings being treated as errors
$

(In reply to Jonathan Wakely from comment #1)
> It's not always possible to make it a hard error and refuse to compile the
> code. The function might call a function that never returns (but isn't
> marked with a noreturn attribute) or might be of the form:
> 
>   int& f(bool b) {
>     if (b) {
>       static int i;
>       return i;
>     }
>   }
> 
> If this is never called with a false argument there's no problem. If it's
> never called at all there's no problem.
> 
> Unless GCC's flow analysis is improved I think the most you can hope for is
> enabling -Wreturn-type by default.
> 

There's several bugs with -Wreturn-type I'd like to see fixed before enabling it by default, for example, bug 55976, bug 68336, and bug 60440

> I use -Werror=return-type, the warning's there already, use it if you want
> it.

Since that works in this case, I'm closing this bug as INVALID.