Omitting return statement in C++
Asked Answered
K

3

23

I just had some weird behavior from a version of g++ for Windows that I got with Strawberry Perl. It allowed me to omit a return statement.

I have a member function that returns a structure consisting of two pointers, called a boundTag:

struct boundTag Box::getBound(int side) {
    struct boundTag retBoundTag;
    retBoundTag.box = this;
    switch (side)
    {
        // set retBoundTag.bound based on value of "side"
    }
}

This function gave me some bad output, and I discovered that it had no return statement. I had meant to return retBoundTag but forgot to actually write the return statement. Once I added return retBoundTag; everything was fine.

But I had tested this function and gotten correct boundTag output from it. Even now, when I remove the return statement, g++ compiles it without warning. WTF? Does it guess to return retBoundTag?

Krystinakrystle answered 4/8, 2010 at 2:30 Comment(2)
You should compile using -Wall. Missing return statements are caught by -Wreturn-type.Hobbyhorse
I tend to turn the warning about a missing return into an error with: -Werror=return-type. Saved me a lot of time.Photic
A
22

Omitting the return statement in a non-void function [Except main()] and using the returned value in your code invokes Undefined Behaviour.

ISO C++-98[Section 6.6.3/2]

A return statement with an expression can be used only in functions returning a value; the value of the expression is returned to the caller of the function. If required, the expression is implicitly converted to the return type of the function in which it appears. A return statement can involve the construction and copy of a temporary object (class.temporary). Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

For example

int func()
{
    int a=10;
    //do something with 'a'
    //oops no return statement
}


int main()
{
     int p=func();
     //using p is dangerous now
     //return statement is optional here 
}

Generally g++ gives a warning: control reaches end of non-void function. Try compiling with -Wall option.

Agree answered 4/8, 2010 at 2:33 Comment(8)
Omitting the return statement is fine. Execution reaching the end of a function without encountering a return statement results in undefined behavior. You can return before reaching the end of the function, or leave via throwing an exception, or just never leave at all, and all would be well defined.Ichor
why using p is dangerous?Lunette
@ajay: That is because is doesn't contain any specified value.Agree
Actually,compiling with -Wall or even -Werror does not show anything for this error. At least not with g++ 4.8.1 on Ubuntu.-Wreturn-type did help though.Enlargement
You are talking about omitting the return statement in a non-void function [Except main()]. But, g++ compiler doesn't give error when missing return statement in main() too.Amphigory
@Amphigory - as per standard you can safely omit return statement in main(), and the returned value will by default be 0.Planogamete
"[...] and using the returned value" You don't need to try to use the function's result to have UB. Just omitting the return statement is enough to have UB, even if the function's result is never used or read. timsong-cpp.github.io/cppwp/stmt.return#2Groome
Since it's undefined behaviours, isn't it valid for a compiler to not a return to the function, just continuing to execute whatever is placed after the function?Jerz
H
16

C and C++ don't require you to have a return statement. It might not be necessary to have one, because the function enters an infinite loop, or because it throws an exception.

Prasoon already quoted the relevant part of the standard:

[Section 6.6.3/2]

A return statement with an expression can be used only in functions returning a value; the value of the expression is returned to the caller of the function. If required, the expression is implicitly converted to the return type of the function in which it appears. A return statement can involve the construction and copy of a temporary object (class.temporary). Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

What it means is that not having a return statement is ok. But reaching the end of the function without returning is undefined behavior.

The compiler can't always detect these cases, so it's not required to be a compile error (it'd have to solve the halting problem to determine whether execution ever actually reaches the end of the function). It is simply undefined what should happen if this occurs. It might appear to work (because the calling function will just look at whatever garbage value is in the location where the return value is supposed to be), it might crash, or make demons fly out of your nose.

Holding answered 4/8, 2010 at 12:15 Comment(1)
Thank you for explaining why it's not a compile error to not have an explicit return statement in non-void functions :)Lunette
S
3

Even though aC++ compiler can't always detect when a function can't execute a return statement, it usually can.

On the bright side, at least g++ makes this easy to detect with the command-line compiler option "-Wreturn-type". You just need to remember to enable it. (It also gets enabled if you use "-Wall".)

Sweatt answered 17/10, 2012 at 17:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.