5.1 void Functions

Subtasks are implemented as functions in C++. The functions discussed in Chapter 4 always return a single value, but there are other forms of subtasks. A subtask might produce several values or it might produce no values at all. In C++, a function must either return a single value or return no values at all. As we will see later in this chapter, a subtask that produces several different values is usually (and perhaps paradoxically) implemented as a function that returns no value. For the moment, however, let us avoid that complication and focus on subtasks that intuitively produce no values at all, and let us see how these subtasks are implemented. A function that returns no value is called a void function. For example, one typical subtask for a program is to output the results of some calculation. This subtask produces output on the screen, but it produces no values for the rest of the program to use. This kind of subtask would be implemented as a void function.

Definitions of void Functions

In C++ a void function is defined in almost the same way as a function that returns a value. For example, the following is a void function that outputs the result of a calculation that converts a temperature expressed in Fahrenheit degrees to a temperature expressed in Celsius degrees. The actual calculation would be done elsewhere in the program. This void function implements only the subtask for outputting the results of the calculation. For now, we do not need to worry about how the calculation will be performed.

void showResults(double fDegrees, double cDegrees)
{
    using namespace std;
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(1);
    cout << fDegrees
         << " degrees Fahrenheit is equivalent to\n"
         << cDegrees << " degrees Celsius.\n";
     return;
}

As this function definition illustrates, there are only two differences between a function definition for a void function and the function definitions we discussed in Chapter 4. One difference is that we use the keyword void where we would normally specify the type of the value to be returned. This tells the compiler that this function will not return any value. The name void is used as a way of saying “no value is returned by this function.” The second difference is that the return statement does not contain an expression for a value to be returned, because, after all, there is no value returned. The syntax is summarized in Display 5.1.

Display 5.1 Syntax for a void Function Definition

An illustration shows the syntax for a “void Function” definition.

A void function call is an executable statement. For example, our function showResults might be called as follows:

showResults(32.5, 0.3);

If this statement were executed in a program, it would cause the following to appear on the screen:

32.5 degrees Fahrenheit is equivalent to
0.3 degrees Celsius.

Notice that the function call ends with a semicolon, which tells the compiler that the function call is an executable statement.

When a void function is called, the arguments are substituted for the formal parameters and the statements in the function body are executed. For example, a call to the void function showResults, which we gave earlier in this section, will cause some output to be written to the screen. One way to think of a call to a void function is to imagine that the body of the function definition is copied into the program in place of the function call. When the function is called, the arguments are substituted for the formal parameters, and then it is just as if the body of the function were lines in the program.

It is perfectly legal, and sometimes useful, to have a function with no arguments. In that case, there simply are no formal parameters listed in the function declaration and no arguments are used when the function is called. For example, the void function initializeScreen, defined next, simply sends a new line command to the screen:

void initializeScreen()
{
    using namespace std;
    cout << endl;
    return;
}

If your program includes the following call to this function as its first executable statement, then the output from the previously run program will be separated from the output for your program:

initializeScreen();

Be sure to notice that even when there are no parameters to a function, you still must include the parentheses in the function declaration and in a call to the function. The next programming example shows these two sample void functions in a complete program.

Programming Example Converting Temperatures

The program in Display 5.2 takes a Fahrenheit temperature as input and outputs the equivalent Celsius temperature. A Fahrenheit temperature F can be converted to an equivalent Celsius temperature C as follows:

C = (5.0/9)(F − 32)

The function celsius shown in Display 5.2 uses this formula to do the temperature conversion.

Display 5.2 void Functions

An illustration shows a code segment  with “void Functions.”
An illustration shows a code segment with the syntax of “void Function.”

Sample Dialogue

I will convert a Fahrenheit temperature to Celsius.
Enter a temperature in Fahrenheit: 32.5
32.5 degrees Fahrenheit is equivalent to
0.3 degrees Celsius.

return Statements in void Functions

Both void functions and functions that return a value can have return statements. In the case of a function that returns a value, the return statement specifies the value returned. In the case of a void function, the return statement simply ends the function call. As we saw in the previous chapter, every function that returns a value must end by executing a return statement. However, a void function need not contain a return statement. If it does not contain a return statement, it will end after executing the code in the function body. It is as if there were an implicit return statement just before the final closing brace } at the end of the function body. For example, the functions initializeScreen and showResults in Display 5.2 would perform exactly the same if we omitted the return statements from their function definitions.

The fact that there is an implicit return statement before the final closing brace in a function body does not mean that you never need a return statement in a void function. For example, the function definition in Display 5.3 might be used as part of a restaurant management program. That function outputs instructions for dividing a given amount of ice cream among the people at a table. If there are no people at the table (that is, if number equals 0), then the return statement within the if statement terminates the function call and avoids a division by zero. If number is not 0, then the function call ends when the last cout statement is executed at the end of the function body.

Display 5.3 Use of return in a void Function

An illustration shows a code segment of “Use of return in a void Function.”

By now you may have guessed that the main part of a program is actually the definition of a function called main. When the program is run, the function main is automatically called and it, in turn, may call other functions. Although it may seem that the return statement in the main part of a program should be optional, officially it is not. Technically, the main part of a program is a function that returns a value of type int, so it requires a return statement. However, the function main is used as if it were a void function. Treating the main part of your program as a function that returns an integer may sound crazy, but that’s the tradition. It might be best to continue to think of the main part of the program as just “the main part of the program” and not worry about this minor detail.1

Self-Test Exercises

  1. What is the output of the following program?

    #include <iostream>
    void friendly();
    void shy(int audienceCount);
    int main()
    {
        using namespace std;
        friendly();
        shy(6);
        cout << "One more time:\n";
        shy(2);
        friendly();
        cout << "End of program.\n";
        return 0;
    }
    
    void friendly()
    {
        using namespace std;
        cout << "Hello\n";
    }
    
    void shy(int audienceCount)
    {
        using namespace std;
        if (audienceCount < 5)
            return;
        cout << "Goodbye\n";
    }
  2. Are you required to have a return statement in a void function definition?

  3. Suppose you omitted the return statement in the function definition for initializeScreen in Display 5.2. What effect would it have on the program? Would the program compile? Would it run? Would the program behave any differently? What about the return statement in the function definition for showResults in that same program? What effect would it have on the program if you omitted the return statement in the definition of showResults? What about the return statement in the function definition for celsius in that same program? What effect would it have on the program if you omitted the return statement in the definition of celsius?

  4. Write a definition for a void function that has three arguments of type int and that outputs to the screen the product of these three arguments. Put the definition in a complete program that reads in three numbers and then calls this function.

  5. Does your compiler allow void main() and int main()? What warnings are issued if you have int main() and do not supply a return 0; statement? To find out, write several small test programs and perhaps ask your instructor or a local guru.

  6. Is a call to a void function used as a statement or is it used as an expression?