Search

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.

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

1b)

Show Solution

1c)

Show Solution

1d)

Show Solution

1e)

Show Solution

1f)

Show Solution

1g)

Show Solution

1h) Extra credit:

Show Solution

1.4a -- A first look at function parameters and arguments
Index
1.3a -- A first look at cout, cin, and endl

446 comments to 1.4 — A first look at functions and return values

  • Cristiano Guerreiro

    My calculator.

  • James Smith

    Regarding the extra credit problem. I like this problem because it requires us to use the google. I had to do a little googling to understand why the program compiles without warnings or errors.

    The program compiles because the compiler sees no errors. The syntax is OK. The logic is OK. Everything is OK. In fact the program seems to be designed to test if a function named return5 was defined (without calling the function). Or maybe the user wanted to print the address of the function retur5() and needs some help.

    Here is result of my research.

    When users click Show Solution they won’t find any explanation why the program compiles. They need to understand that compilers can’t catch all human mistakes. I think the users should know why the program compiles. At least you could mention pointers in the Show Solution text. Or maybe there is no need to do anything. Those who really want to learn will want to understand. Their curiosity should drive them to search for answers.

  • African

    Hello Alex, Today I tried to make a basic, mini calculator and I was having trouble outputting the result of the inputs, maybe you can help me and tell me how to fix it, please. 🙂

    • Alex

      You have a good start. You’ve got functions to ask the user for inputs. Your program is well structured so far. But then all you do is print the inputs and the user-entered operator. At no point do you actually do any calculation. You need one more function that takes the two inputs and the operator and returns the result of the calculation (which main can then print).

    • Kaif Ahsan

      Hi, can you please explain the function of this chunk of code at the end of your program?
          

      • Alex

        std::cin.clear() clears any previous errors that have occurred, so the next std::cin statements will work properly.
        std::cin.ignore(32767, ‘\n’) discards up to 32767 character (or until a ‘\n’ character is found) inside std::cin. In practical terms, this gets rid of any input that was entered but not used yet.
        std::cin.get() tries to get the next character from std::cin. Because we cleared out all of the characters in the previous line, there aren’t any left. Therefore, it has to ask the user to enter one. We use this as a way to pause the program.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter