1

Please see the code sample below. The statement return (&i) in function fun_ret_loc_ptr() returns a warning:"function returns address of local variable". On the other hand the statement return a in function fun_ret_loc_var() doesn't do so.

#include <stdio.h>
int* fun_ret_loc_ptr()
{
   int i = 10;
   return (&i);
}

int fun_ret_loc_var()
{
   int a = 20;
   return a;
}

int main()
{
   printf("val frm local ptr = %d\n", *fun_ret_loc_ptr());
   printf("val frm local var = %d\n", fun_ret_loc_var());
}

I understand that in the first function the address returned (return (&i);) refereed to a memory location that was part of the stack frame corresponding to function fun_ret_loc_ptr(). Once this function returned the stack frame (Activation Record) would be destroyed. Same thing should be applicable to the variable 'a' (return a;) in function fun_ret_loc_var(). Even though it is returned, when it is being used in main, the memory corresponding to 'a' would have died.

From the perspective of "return" statement's functionality, why does this difference arise?

abhi4eternity
  • 448
  • 3
  • 8
  • 19

4 Answers4

6

Returning a variable by value copies it, and it is therefore safe to use it after returning from the function.

Returning a reference (or a pointer) to a local variable is not safe (because the reference / pointer is no longer valid after returning from the function).

Now, if the program seemed to do what you expect, that is pure coincidence. This is known as Undefined Behaviour. In fact, the result may be anything (from your car blowing up to carefully making lunch for the coming three weeks straight. It is just undefined)

sehe
  • 374,641
  • 47
  • 450
  • 633
2

You covered the explanation pretty well at the end of your post. Your only "mistake" is saying that the variable a "dies" at the end of the function call. Indeed it does die, but a copy of a is returned, not the a from the function stack. Therefore, there is no problem in accessing the return value of that function.

Tudor
  • 61,523
  • 12
  • 102
  • 142
  • How does the main function know to which location is the returned value is returned if returned by value? – abhi4eternity Nov 18 '11 at 15:11
  • 1
    @Abhijeet: During return, a function pushes its return value to the stack. The caller function then retrieves (e.g: pops) it from the stack. – jweyrich Nov 18 '11 at 15:16
  • 2
    @jweyrich Where the return value is copied depends on the calling convention in use. It might be passed back in a register, or across several registers. – James Nov 18 '11 at 17:10
  • @James: good remark! :) That's also the case in implementations for other architectures, like MIPS. – jweyrich Nov 18 '11 at 17:30
  • In fact, every platform I've used for the past 20 years uses register return for primitive types like ints, pointers, and floats, not stack return. – Russell Borogove Jul 01 '12 at 06:52
1

You can think of an analogy with passing arguments by value or by reference.

Here, you return the value by reference, or by value. If you return the value by value, then the value is available in the caller. If you return the value by reference, then the reference of the value is returned to the caller. To access the value, the caller has to dereference, but the reference does not point to any valid value anymore.

Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
0

Functions don't return variables; they return values. Whether the value came from a local variable is irrelevant; even if it didn't, it came from a "local expression" (my term) whose lifetime is even shorter than that of a local variable. The problem with returning a pointer to a local (assuming it's automatic, not static) variable is that the value of the pointer is invalid and any use of it after the function returns results in undefined behavior.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711