- Learn C++ - http://www.learncpp.com -

1.4 — A first look at functions and return values

A function is a reusable sequence of statements designed to do a particular job. You already know that every program must have a function named main() (which is where the program starts execution). However, most programs use many functions.

Often, your program needs to interrupt what it is doing to temporarily do something else. You do this in real life all the time. For example, you might be reading a book when you remember you need to make a phone call. You put a bookmark in your book, make the phone call, and when you are done with the phone call, you return to your book where you left off.

C++ programs work the same way. A program will be executing statements sequentially inside one function when it encounters a function call. A function call is an expression that tells the CPU to interrupt the current function and execute another function. The CPU “puts a bookmark” at the current point of execution, and then calls (executes) the function named in the function call. When the called function terminates, the CPU goes back to the point it bookmarked, and resumes execution.

The function initiating the function call is called the caller, and the function being called is the callee or called function.

Here is a sample program that shows how new functions are defined and called:

This program produces the following output:

Starting main()
In doPrint()
Ending main()

This program begins execution at the top of function main(), and the first line to be executed prints Starting main(). The second line in main() is a function call to the function doPrint(). At this point, execution of statements in main() is suspended, and the CPU jumps to doPrint(). The first (and only) line in doPrint prints In doPrint(). When doPrint() terminates, the caller (main()) resumes execution where it left off. Consequently, the next statement executed in main prints Ending main().

Note that function calls are made by using the function name, plus an empty set of parenthesis (). We’ll talk about what this set of parenthesis is in the next lesson. For now, just note that if you forget them, your program may not compile (and if it does, the function will not be called as expected).

Rule: Don’t forget to include parenthesis () when making a function call.

Return values

When the main() function finishes executing, it returns an integer value (typically 0) back to the operating system (the caller) by using a return statement.

When you write your own functions, you get to decide whether a given function will return a value to the caller or not. This is done by setting the return type of the function in the function’s definition. The return type is the type declared before the function name. Note that the return type does not indicate what specific value will be returned. It only indicates what type of value will be returned.

Then, inside the called function, we use a return statement to indicate the specific value being returned to the caller. The actual value returned from a function is called the return value.

Let’s take a look at a simple function that returns an integer value, and a sample program that calls it:

In the first function call of return5(), the function returns the value of 5 back to the caller, which passes that value to std::cout to be output.

In the second function call of return5(), the function returns the value of 5 back to the caller. The expression 5 + 2 is then evaluated to 7. The value of 7 is passed to cout to be output.

In the third function call of return5(), the function returns the value of 5 back to the caller. However, main() does nothing with the return value so nothing further happens (the return value is ignored).

Note: Return values will not be printed unless the caller sends them to std::cout. In the last case above, the return value is not sent to std::cout, so nothing is printed.

Return values of type void

Functions are not required to return a value. To tell the compiler that a function does not return a value, a return type of void is used. Let’s look at the doPrint() function from the program above:

This function has a return type of void, indicating that it does not return a value to the caller. Because it does not return a value, no return statement is needed.

Here’s another example of a function that returns void, and a sample program that calls it:

In the first function call to returnNothing(), the function prints “Hi” and then returns nothing back to the caller. Control returns to main() and the program proceeds.

The second function call to returnNothing() won’t even compile. Function returnNothing() has a void return type, meaning it doesn’t return a value. However, function main() is trying to send this nothing value to std::cout to be printed. std::cout can’t handle “nothing” values, as it doesn’t know what to do with them (what value would it output?). Consequently, the compiler will flag this as an error. You’ll need to comment out this line of code in order to make your code compile.

The only valid thing you can do with void return values is ignore them.

Returning to main

You now have the conceptual tools to understand how the main() function actually works. When the program is executed, the operating system makes a function call to main(). Execution then jumps to the top of main. The statements in main are executed sequentially. Finally, main returns an integer value (usually 0) back to the operating system. This is why main is defined as int main().

Why return a value back to the operating system? This value is called a status code, and it tells the operating system (and any other programs that called yours) whether your program executed successfully or not. By consensus, a return value of 0 means success, and a positive return value means failure.

Note that the C++ standard explicitly specifies that main() must return an int. However, if you do not provide a return statement in main, the compiler will return 0 on your behalf. That said, it is best practice to explicitly return a value from main, both to show your intent, and for consistency with other functions (which will not let you omit the return value).

For now, you should also define your main() function at the bottom of your code file. We’ll talk about why shortly, in section 1.7 -- Forward Declarations [1].

A few additional notes about return values

First, if a function has a non-void return type, it must return a value of that type (using a return statement). The only exception to this rule is for function main(), which will assume a return value of 0 if one is not explicitly provided.

Second, when a return statement is reached in a function, the function returns back to the caller immediately at that point. Any additional code in the function is ignored.

A function can only return a single value back to the caller. The function may, however, use any logic at its disposal to determine which specific value to return. It may return a single number (return 5). It may return the value of a variable or an expression (both of which evaluate to a single value). Or it may pick a single value from a set of possible values (which is still just a single value).

There are ways to work around only being able to return a single value back to the caller, which we will discuss when we get into the in-depth section on functions.

Finally, note that a function is free to define what its return value means. Some functions use return values as status codes, to indicate whether they succeeded or failed. Other functions return a calculated or selected value. Other functions return nothing. What the function returns and the meaning of that value is defined by the function’s author. Because of the wide variety of possibilities here, it’s a good idea to leave a comment on your functions indicating not just what they return, but also what the return value means.

Reusing functions

The same function can be called multiple times, which is useful if you need to do something more than once.

This program produces the following output:

Enter an integer: 5
Enter an integer: 7
5 + 7 = 12

In this case, main() is interrupted 2 times, once for each call to getValueFromUser(). Note that in both cases, the value read into variable a is passed back to main() via the function’s return value and then assigned to variable x or y!

Note that main() isn’t the only function that can call other functions. Any function can call another function!

This program produces the following output:

Starting main()
A
B
Ending main()

Nested functions

Functions can not be defined inside other functions (called nesting) in C++. The following program is not legal:

The proper way to write the above program is:

Quiz time

Inspect the following programs and state what they output, or whether they will not compile.

1a)

Show Solution [2]

1b)

Show Solution [2]

1c)

Show Solution [2]

1d)

Show Solution [2]

1e)

Show Solution [2]

1f)

Show Solution [2]

1g)

Show Solution [2]

1h) Extra credit:

Show Solution [2]

1.4a -- A first look at function parameters and arguments [3]
Index [4]
1.3a -- A first look at cout, cin, and endl [5]