5

Is it legal C++ to define a function with a non-void return type that allows control to reach the end of the function instead of reaching a return statement?

gcc and clang only issue warnings for this. Is code that does this legal or are these compilers just being generous?

gcc:

warning: no return statement in function returning non-void [-Wreturn-type]

clang:

warning: control reaches end of non-void function [-Wreturn-type]

If this is legal, is there a defined behavior for what value will be returned?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Praxeolitic
  • 22,455
  • 16
  • 75
  • 126
  • One of those warnings that really any compiler should promote to an error. – Bathsheba Nov 19 '14 at 08:13
  • It has at least one use. The inspiration for this question was the answer to this question. http://stackoverflow.com/questions/27011345/generate-mangled-names-from-source-code?noredirect=1#comment42549548_27011345 – Praxeolitic Nov 19 '14 at 08:13

2 Answers2

5

As already stated by Bathsheba, flowing off the end of a non-void function is indeed undefined behavior. The reason why this is a warning, not an error, is that you might be able to proof that this will never happen. For example consider this:

// My magic function.
// It is forbidden to call it with values between -5 and 5
bool fun (int i) {
    if (i >= 5)
        return true;
    if (i <= -5)
        return false;
}

Now you have well defined behavior as long as the users of the function read the comment carefully. This is obviously a dangerous thing to do, so the compiler warns you not to do it.

Edit: As MSalters mentioned, this is less dangerous for private member functions because the class invariant can guarantee that the function is never used incorrectly. Consider this example:

// Every member function of SomeClass makes sure 
// that i_ is in the legal range when it's done
class SomeClass {
    public:
        SomeClass () : i_{27} {}
    // Possibly more public or private functions that all make sure i_ stays valid
    private:
        bool foo () {if (i_ > 3) return true;}
        int i_;
};

Now you (as the class maintainer) can make sure that i_ is always at least 4 and foo will always work fine. Personally, I would still avoid that because it hurts maintainability and readability, but it is better than the free version because now "only" all class maintainers need to worry about this invariant/can make a mistake.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
4

From C++ Standard, 6.6.3:

Flowing off the end of a function is equivalent to a return with no value; this results in undefined behaviour in a value-returning function.

So not having an explicit return value is undefined behaviour.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Does reading the contents of the returned value result in UDB, is the function call UDB, or is the function's definition UDB? – Praxeolitic Nov 19 '14 at 08:13
  • The standard doesn't seem to specify that. I imagine it's futile to try to pinpoint the exact place, particularly with an inline function. – Bathsheba Nov 19 '14 at 08:14
  • Right, if a program has UDB then it's *all* UDB but what I mean is, if a program only defines but doesn't call the function, is it UDB? What about call without reading the return value? Does the standard specify? – Praxeolitic Nov 19 '14 at 08:16
  • 2
    You're safe so long as program control doesn't reach the closing `}` of the function with the missing `return` value. – Bathsheba Nov 19 '14 at 08:22
  • To clarify: this means the Undefined Behavior may occur only for some inputs. It's the actual flow at runtime which defines UB, not the potential flow at compile time. However, the compiler **may** assume that all code paths which unconditionally lead to that closing `}` are unreachable. It may even assume that inputs which lead to UB do not actually occur at runtime and optimize based on that. – MSalters Nov 19 '14 at 09:55
  • May be helpeful to link to the [closest draft](http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents) you are quoting so others can check it out themselves. – Shafik Yaghmour Nov 19 '14 at 10:37