14.11 – Return by address

by subbu on January 24, 2014

Return by value:

It is the simplest and safest method to return a value from a function. When a value is returned by a function, only the copy of that value is returned to the calling function. The expression with the return statement can be a constant, variable or an expression.

The advantage with the return by value is that we can return the values of local variables defined with in the function because the variables are evaluated before the function goes out of scope, and a copy of the value is returned to the caller, there would be no problem when the variable goes out of scope at the end of the function.

int sum(int x,int y)
{
int z;
z=x+y;
return z;  /* copy of value is returned */
}                /* goes out of scope          */

Here z is a local variable to the function sum(). It goes out of scope after returning the value of z to the caller
However, it has disadvantage that it takes much time while returning big structures and objects
To improve the performance we may return the address of local variable to the caller called return by address.

Return by address:

Return by address involves returning the address of a variable like return by value. Jus like return by value, we can’t return the address of a constant and an expression but, the address of a variable can be returned.

We can’t return the address of a local variable belongs to the function because the variable goes out of scope after returning the address to the caller.

short* sub()
{
short x=45;
return &x;
}

Here x goes out of scope after returning the address to the caller. It results warning in most of the compilers but, somehow manages to get the value through dereferencing.

return by address

/* demo.c */
#include
short* sub();
int main()
{
short *p;
p=sub();
printf("%d",*p);
return 0;
}
short* sub()
{
short x=45;
return &x;
}

Output on Turbo C:
45

Output on Ubuntu gcc:

$gcc –o demo demo.c
demo.c: In function 'sub':
demo.c:13: warning: function returns address of local variable
$./demo
45
$

In the example though x goes out of scope, its address is returned to the caller, some how pointer p in the caller could manage to get the value of x but, it may not be possible to modify and access again like

*p=*p+20;
printf("\n%d",*p);

It results garbage value.

/* demo.c */
#include
short* sub();
int main()
{
short *p;
p=sub();
printf("%d",*p);
*p=*p+20;
printf("\n%d",*p);
return 0;
}
short* sub()
{
short x=45;
return &x;
}

Output on Turbo C:
45
695    //garbage value

Output on Ubuntu gcc:

$gcc –o demo demo.c
demo.c: In function 'sub':
demo.c:15: warning: function returns address of local variable
$./demo
45
257    //garbage value
$

return by address – static local variable

It can be concluded that, it is not the best practice to return the address of a local variable to the caller because variable goes out of scope once the address is returned. We can’t perform further operations through the pointer.

The best solution is defining the local variable as static variable, so that variable would not get de-allocated even after the completion of function execution because scope of static variable is along the program.

#include
short* sub();
int main()
{
short *p;
p=sub();
printf("%d",*p);
*p=*p+20;
printf("\n%d",*p);
return 0;
}
short* sub()
{
static short x=45;
return &x;
}

Output in Turbo C:
45
65

Output on Ubuntu gcc:

$gcc –o demo demo.c
$./demo
45
65
$

Though x is a local variable, its scope is along the program because the scope of static variable is along the program. Once the caller gets the address then can be accessed any time and for any number of times through dereferencing.

Conclusion:

Most of the times, return by value solve our needs. It is the most flexible and safest way to return a single value to the caller. However return by address can also be useful, particularly when working with dynamically allocated structs or objects. When using return by address, make sure that you are not returning the address of a variable that will go out of scope on completion of function execution.

Previous post:

Next post: