Reputation: 19
I would like to know the output of the below program. Main concern is what happens when we do not use return statement in the calling function?
int sum(int x, int y)
{
//return x+y;
}
int main()
{
int res=0;
res=sum(1,2);
printf("res = %d\n",res);
}
in the above function sum()
, if I use return x+y
; it will print 3 as output?
What happens if I do not use return statement?
Upvotes: 1
Views: 2304
Reputation: 40695
melpomene's answer is 100% correct from the pure language point of view: Returning from a non-void function without a return value invariably results in undefined behavior. After that, all bets are off.
I'm going to add to this, what is likely going to happen:
When you call a function, the compiler has a set of rules that it follows on how the parameters and return value are passed to the callee. These rules are along the lines of "If the first argument is an integral type, put it into register eax
before invoking the callee". So, if you say foo(42)
, the compiler emits code to load 42
into the register eax
, and then to call foo
, which then just examines the value it finds in register eax
to know what was passed.
The same happens for the return value. There is a defined place where the caller expects the return value (this may be a register or a memory location on the stack), and it's the callee's obligation to actually put a sensible value there.
So, when you forget to name a return value, the return value will simply not be set. Whatever happens to be in the respective register / memory location will be interpreted as the return value by the caller. What exactly is effectively "passed back" to the caller depends 100% on how the callee happens to be compiled, and it may be deterministic. Consider this code snippet:
int getSecret() {
return 42;
}
int checkSecret(int guess) {
int secret = getSecret();
//return secret == guess;
}
int main() {
printf("The secret is %d.\n", checkSecret(0));
}
If you compile and run this code, you may find that it correct prints the secret value 42
. Why? Simple: When getSecret()
returns the secret value, it places it where checkSecret()
expects to find the return value. And this may happen to be the same register as where main()
expects to find the return value of checkSecret()
.
From the language perspective, that's perfectly ok: When checkSecret()
returns without setting a return value, the language allows anything to happen, including leaking the secret. This is why forgetting the return value can be a security hole. It may allow an attacker to either extract information that they are not supposed to know, or to trigger code execution paths that are impossible in correct behavior because a function "returns" a value that's not within the expected return value range.
Upvotes: 2
Reputation: 85907
See 6.9.1 (Function definitions) / 12 in the C11 draft standard (the same language appears in C99):
- 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 C90 there was mostly equivalent language in 6.6.6.4 (The return
statement):
If a
return
statement without an expression is executed, and the value of the function call is used by the caller, the behavior is undefined. Reaching the}
that terminates a function is equivalent to executing areturn
statement without an expression.
The difference is that (from C99 on) having return;
with no expression in a non-void function is an error.)
In your case the }
of sum
is reached (no return
statement was executed) and the return value is used:
res=sum(1,2);
Therefore your code has undefined behavior: Anything can happen, from a garbage value in res
to an infinite loop or crash.
Upvotes: 7