7.3. The return Statement
A return statement terminates the function that is currently executing and returns control to the function that called the now-terminated function. There are two forms of return statements:
return;
return expression;
7.3.1. Functions with No Return Value
A return with no value may be used only in a function that has a return type of void. Functions that return void are not required to contain a return statement. In a void function, an implicit return takes place after the function's final statement.Typically, a void function uses a return to cause premature termination of the function. This use of return parallels the use of the break (Section 6.10, p. 212) statement inside a loop. For example, we could rewrite our swap program to avoid doing any work if the values are identical:
This function first checks if the values are equal and if so exits the function. If the values are unequal, the function swaps them. An implicit return occurs after the last assignment statement.A function with a void return type ordinarily may not use the second form of the return statement. However, a void function may return the result of calling another function that returns void:
// ok: swap acts on references to its arguments
void swap(int &v1, int &v2)
{
// if values already the same, no need to swap, just return
if (v1 == v2)
return;
// ok, have work to do
int tmp = v2;
v2 = v1;
v1 = tmp;
// no explicit return necessary
}
Attempting to return any other expression is a compile-time error.
void do_swap(int &v1, int &v2)
{
int tmp = v2;
v2 = v1;
v1 = tmp;
// ok: void function doesn't need an explicit return
}
void swap(int &v1, int &v2)
{
if (v1 == v2)
return false; // error: void function cannot return a value
return do_swap(v1, v2); // ok: returns call to a void function
}
7.3.2. Functions that Return a Value
The second form of the return statement provides the function's result. Every return in a function with a return type other than void must return a value. The value returned must have the same type as the function return type, or must have a type that can be implicitly converted to that type.Although C++ cannot guarantee the correctness of a result, it can guarantee that every return from a function returns a result of the appropriate type. The following program, for example, won't compile:
The return from within the while loop is an error because it fails to return a value. The compiler should detect this error.The second error occurs because the function fails to provide a return after the while loop. If we call this function with one string that is a subset of the other, execution would fall out of the while. There should be are turn to handle this case. The compiler may or may not detect this error. If a program is generated, what happens at run time is undefined.
// Determine whether two strings are equal.
// If they differ in size, determine whether the smaller
// one holds the same characters as the larger one
bool str_subrange(const string &str1, const string &str2)
{
// same sizes: return normal equality test
if (str1.size() == str2.size())
return str1 == str2; // ok, == returns bool
// find size of smaller string
string::size_type size = (str1.size() < str2.size())
? str1.size() : str2.size();
string::size_type i = 0;
// look at each element up to size of smaller string
while (i != size) {
if (str1[i] != str2[i])
return; // error: no return value
}
// error: control might flow off the end of the function without a return
// the compiler is unlikely to detect this error
}

Return from main
There is one exception to the rule that a function with a return type other than void must return a value: The main function is allowed to terminate without a return. If control reaches the end of main and there is no return, then the compiler implicitly inserts a return of 0.Another way in which the return from main is special is how its returned value is treated. As we saw in Section 1.1 (p. 2), the value returned from main is treated as a status indicator. A zero return indicates success; most other values indicate failure. A nonzero value has a machine-dependent meaning. To make return values machine-independent, the cstdlib header defines two preprocessor variables (Section 2.9.2, p. 69) that we can use to indicate success or failure:
Our code no longer needs to use the precise machine-dependent values. Instead, those values are defined in cstdlib, and our code need not change.
#include <cstdlib>
int main()
{
if (some_failure)
return EXIT_FAILURE;
else
return EXIT_SUCCESS;
}
Returning a Nonreference Type
The value returned by a function is used to initialize a temporary object created at the point at which the call was made. A temporary object is an unnamed object created by the compiler when it needs a place to store a result from evaluating an expression. C++ programmers usually use the term "temporary" as an abreviation of "temporary object."The temporary is initialized by the value returned by a function in much the same way that parameters are initialized by their arguments. If the return type is not a reference, then the return value is copied into the temporary at the call site. The value returned when a function returns a nonreference type can be a local object or the result of evaluating an expression.As an example, we might want to write a function that, given a counter, a word, and an ending, gives us back the plural version of the word if the counter is greater than one:
We might use such a function to print a message with either a plural or singular ending.This function either returns a copy of its parameter named word or it returns an unnamed temporary string that results from adding word and ending. In either case, the return copies that string to the call site.
// return plural version of word if ctr isn't 1
string make_plural(size_t ctr, const string &word,
const string &ending)
{
return (ctr == 1) ? word : word + ending;
}
Returning a Reference
When a function returns a reference type, the return value is not copied. Instead, the object itself is returned. As an example, consider a function that returns a reference to the shorter of its two string parameters:
The parameters and return type are references to const string. The strings are not copied either when calling the function or when returning the result.
// find longer of two strings
const string &shorterString(const string &s1, const string &s2)
{
return s1.size() < s2.size() ? s1 : s2;
}
Never Return a Reference to a Local Object

This function will fail at run time because it returns a reference to a local object. When the function ends, the storage in which ret resides is freed. The return value refers to memory that is no longer available to the program.
// Disaster: Function returns a reference to a local object
const string &manip(const string& s)
{
string ret = s;
// transform ret in some way
return ret; // Wrong: Returning reference to a local object!
}

Reference Returns Are Lvalues
A function that returns a reference returns an lvalue. That function, therefore, can be used wherever an lvalue is required:
It may be surprising to assign to the return of a function, but the return is a reference. As such, it is just a synonym for the element returned.If we do not want the reference return to be modifiable, the return value should be declared as const:
char &get_val(string &str, string::size_type ix)
{
return str[ix];
}
int main()
{
string s("a value");
cout << s << endl; // prints a value
get_val(s, 0) = 'A'; // changes s[0] to A
cout << s << endl; // prints A value
return 0;
}
const char &get_val(...
Never Return a Pointer to a Local Object
The return type for a function can be most any type. In particular, it is possible for a function to return a pointer. For the same reasons that it is an error to return a reference to a local object, it is also an error to return a pointer to a local object. Once the function completes, the local objects are freed. The pointer would be a dangling pointer (Section 5.11, p. 176) that refers to a nonexistent object.
7.3.3. Recursion
A function that calls itself, either directly or indirectly, is a recursive function. An example of a simple recursive function is one that computes the factorial of a number. The factorial of a number n is the product of the numbers from 1 to n. The factorial of 5, for example, is 120.
1 * 2 * 3 * 4 * 5 = 120
Exercises Section 7.3.2
Exercise 7.17:When is it valid to return a reference? A const reference?Exercise 7.18:What potential run-time problem does the following function have?
Exercise 7.19:Indicate whether the following program is legal. If so, explain what it does; if not, make it legal and then explain it:
string &processText() {
string text;
while (cin >> text) { /* ... */ }
// ....
return text;
}
A natural way to solve this problem is recursively:
int &get(int *arry, int index) { return arry[index]; }
int main() {
int ia[10];
for (int i = 0; i != 10; ++i)
get(ia, i) = 0;
}
A recursive function must always define a stopping condition; otherwise, the function will recurse "forever," meaning that the function will continue to call itself until the program stack is exhausted. This is sometimes called an "infinite recursion error." In the case of factorial, the stopping condition occurs when val is 1.As another example, we can define a recursive function to find the greatest common divisor:
// calculate val!, which is 1*2 *3 ... * val
int factorial(int val)
{
if (val > 1)
return factorial(val-1) * val;
return 1;
}
In this case the stopping condition is a remainder of 0. If we call rgcd with the arguments (15, 123), then the result is three. Table 7.1 on the next page traces the execution.
// recursive version greatest common divisor program
int rgcd(int v1, int v2)
{
if (v2 != 0) // we're done once v2 gets to zero
return rgcd(v2, v1%v2); // recurse, reducing v2 on each call
return v1;
}
Table 7.1. Trace of rgcd(15,123)
v1v2Return15123rgcd(123, 15)12315rgcd(15, 3)153rgcd(3, 0)303The last call,satisfies the stopping condition. It returns the greatest common denominator, 3. This value successively becomes the return value of each prior call. The value is said to percolate upward until the execution returns to the function that called rgcd in the first place.
rgcd(3,0)

Exercises Section 7.3.3
Exercise 7.20:Rewrite factorial as an iterative function.Exercise 7.21:What would happen if the stopping condition in factorial were:
if (val != 0)