implicit return value in C with no explicit return in a function that should return non-void

887 Views Asked by At

I have some legacy C code that I compiled with gcc version 4.9.2 on Linux with return-type warning on [-Wreturn-type]. I have a function as below:

int somefn() {
   // .. do something ..
   // no explicit return statement
}

and the caller had the call as below:

if (somefn()){
   // handling of success
}
else {
  // handling of failure
}

When warnings were suppressed, compilation+linking went all ok, and at runtime, we may get surprises, What could go wrong?

2

There are 2 best solutions below

2
On BEST ANSWER

I compiled with gcc version 4.9.2 on Linux with return-type warning on [-Wreturn-type] The caller expected a true (in C, interpreted as non-zero) for success and 0 for failure. This is what was happening. Since a function that returns non-void, when called, space is created on the stack for the return value, then context is switched to the callee, and finally, when the control comes back to the caller, context is switched back popping all local variables from stack and keeping the return value there on stack to be popped by the caller after return from callee. Thus, having no explicit return statement caused some value to be returned. That is equivalent to having explicit return statement as ‘return 1;’ or 'return 0;' as appropriate. So, better (of course) would be to have explicit return statement e.g.

int somefn() {
   // .. do something ..
   if (..somecond..)
    return 0; // failure
   else
    return 1; // success
}

To avoid surprises, I would say, compilers should flag 'no return statement in function returning non-void' as error.

0
On

Quoting C11, chapter §6.9.1, Function Definitions, Semantics

If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

So, the standard specifies the semantics of the function definition and it clearly states that (for a non-void function return type) a function which terminates without a return statement and the returned value is used in caller causes undefined behavior.

So, it accepts that syntactically writing a function as such will be possible, but attempt to make use of that will be UB. It does not state this as a constraint violation and I see no reason for a conforming compiler to produce an "error".

In case you want strict check (which is recommended, by the way), use -Werror option.