If a Function Returns No Value, With a Valid Return Type, Is It Okay to For the Compiler to Return Garbage

If a function returns no value, with a valid return type, is it okay to for the compiler to return garbage?

In C++, such code has undefined behaviour:

[stmt.return]/2 ... 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. ...

Most compilers will produce a warning for code similar to that in the question.

The C++ standard does not require this to be a compile time error because in the general case it would be very difficult to correctly determine whether the code actually runs off the end of the function, or if the function exits through an exception (or a longjmp or similar mechanism).

Consider

int func3() {
func4();
}

If func4() throws, then this code is totally fine. The compiler might not be able to see the definition of func4() (because of separate compilation), and so cannot know whether it will throw or not.

Furthermore, even if the compiler can prove that func4() does not throw, it would still have to prove that func3() actually gets called before it could legitimately reject the program. Such analysis requires inspection of the entire program, which is incompatible with separate compilation, and which is not even possible in the general case.

If a function with int as specified return type, does not have any return statement, i.e. does not return a value, will it return garbage value?

In C, it will invoke undefined behavior if the return value is used:

(C11, 6.9.1p12) "If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined."

In C++, the function call is undefined behavior:

(C++11, 6.6.3p2) "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."

Why does the C++ function without a return statement return a value?

Not returning from a non-void function is undefined behavior. This means anything can happen. One of those things is actually returning a value.

However, this is not behavior you can rely upon. Crashing the program, printing garbage, etc, are all valid behaviors. Turn on compiler warnings, they will tell you that you are making a mistake.

What happens if you don't return a value in C++?

Did another SomeStruct get created and initialized somewhere implicitly?

Think about how the struct is returned. If both x and y are 32 bits, it is too big to fit in a register on a 32-bit architecture, and the same applies to 64-bit values on a 64-bit architecture (@Denton Gentry's answer mentions how simpler values are returned), so it has to be allocated somewhere. It would be wasteful to use the heap for this, so it has to be allocated on the stack. But it cannot be on the stack frame of your getSomeStruct function, since that is not valid anymore after the function returns.

The compiler instead has the caller tells the called function where to put the result (which is probably somewhere on the stack of the caller), by passing the called function a hidden pointer to the space allocated to it. So, the place where it is being set to zero is on the caller, not on your getSomeStruct function.

There are also optimizations like the "named value return optimization" where extra copies can be elided. So, had you used the missing return, the result would be created directly on the space allocated by the caller, instead of creating a temporary and copying it.

To know more about what is happening, you have to look at the caller function. Is it initializing (to zero) an "empty" SomeStruct to which you later assign the return value of your getSomeStruct function? Or is it doing something else?

c++ class member operator definition with no return value

Some random garbage value from memory?

Most likely. Formally, as already noted, the behaviour is undefined, so anything is allowed, but most implementations will return some garbage value.

Why does the compiler not enforce to add a return to the operator definition if it is expected to return a value with myClass type?

Because a function that has a return type doesn't need to return at all. There can be good reasons for having functions with a return type that always throw an exception, for example, in which case a diagnostic for a missing return statement is only a hindrance. That could even happen in ways the compiler cannot possibly see, for example when the last statement of the function is a call to another function that doesn't return normally.

Sort of an example:

int negate(int i) {
if (i >= -INT_MAX)
return i;

/* i cannot be negated */
abort();
}

You might write functions like this to prevent silently going on when INT_MIN is passed, to make debugging easier. In this case, the fact that there is no return statement after abort(); is not a problem. Admittedly, this function does have a return statement, but as far as the compiler knows, it's possible for this function to return by reaching the closing }.

Some compilers do have an option for warning about a missing return statement, so you could try to turn up your warning level.

C++ Function Automatic Return Value?

The calling convention of your platform specifies how the function returns the value it wants to be returned to the caller (e.g: saved in a register). Since the register exists, the caller code just takes the value it finds there, possibly garbage, or the actual good value by chance. Either way, your program invokes undefined behaviour, it cannot be trusted any more.

The solution is to turn the compiler warnings on. E.g, on GCC or Clang:

g++ -Wall -Wextra -Werror

C++ omitting return type

You cannot always trust the compiler as different compilers have different checking conditions while compiling. If you don't return in a function that need to return, even compiled successfully, the result is undefined. This is why your program crash. You should always try to avoid this.



Related Topics



Leave a reply



Submit