Intro Essentials of C++
 

 
Essentials of C++: Section III
 
 
 

Functions

C++ programs are composed of some number of functions representing groups of instructions. They are the building blocks upon which programs are built. All programs must have a function called 'main'. The first instruction in 'main' becomes the first instruction in the program.

A. Function Declarations
One can abstractly view a function as a black box that is capable of:

  • receiving, through a parameter list, the information to be processed;
  • processing that information according to some set of instructions;
  • returning information through the parameter list as well as through a built-in return mechanism.

In C++, functions must be declared before they can be used. Except for 'main' which is always declared and defined at the same time, most C++ functions are declared at the beginning of a file (as prototypes) and defined later in the same file. (The most common exceptions to this are functions that are members of a class - see Section XI.)

A function declaration (prototype) starts with a return type followed by the function's name and a list of types of values to be received and/or returned by the function. The list of values to be received and/or returned is enclosed in parentheses and is called the parameter list. The general form is as follows:

some_type_name function_name (parameter_list);

and a specific example would be:

double CalculateAverage(int var1, int var2, double var3);

Except for the function name and the parentheses themselves the elements are optional. Functions can return any type except an array or a function type. If no type is included, the default is 'int'. Functions that return nothing have a return type of void.

One can consider the declaration of the return type as a description of one of the mechanisms a function has to communicate with the rest of the program. In C++, one function calls another to get the 'called' function to execute its instructions and, if declared to do so, to return some value(s). The parameter list represents a second, more complex communication path (actually a set of paths – one for each parameter) between the function doing the calling and the called function. If no communication is needed between two functions (other than to simply have the called function begin executing and, possibly, return one value), the parameter list is empty - the parentheses exist but there is nothing inside them.

When the function to be called requires information from the calling function or when it is desired that the 'communication paths' (other than the one provided by the return mechanism) be used to return information, a parameter list is included in the parentheses. Each element of the parameter list is declared using a format similar to that used in variable and constant declarations. The type of the parameter (what type of value will be passed along the path) is written first, followed by the name for of the identifier to be used both as the variable receiving and/or returning the information being passed and in the code for the function. (Technically, the identifier name is not required in the declaration, but in this text it is considered good style to include it.) Commas separate the elements of the list and a semicolon appears after the closing parenthesis.

To indicate that a parameter is to be used both to return and possible receive a value, the '&' symbol is placed after the type and before the identifier name. Such parameters are called reference parameters . Arrays types do not need this symbol. (A more complex mechanism for returning values via the parameter list involves the use of pointer declarations. See the discusion on pointers in Section X.)

It is possible to provide default values for parameters by including an equal sign (=) and a value after the identifier. Such default declarations must come at the end of the parameter list. One can also declare that a function will receive a variable number of values by placing an ellipsis (…) at the end of the list. To implement this capability, requires the use of the "stdarg.h" header file and some special coding. If interested, read the discussion of the "stdarg.h" header file in your C++ manual.

Here are a few examples of function declarations:

void function1();
// receives nothing and returns nothing

void function2(int value1, double value2, char ch);
// returns nothing and receives an int, a double, and a char

double function3(Type1 value1, int value2 = 0);

// returns a double and receives a value of user defined type 'Type1' and
// an integer whose value will be 0 if no value is passed

void function4(int & value1 char& str, double value2)

// returns both an int and a character (via the use of the '&' symbol)
// receives a double

int function5(char& str, double value1, ...)

// returns an int (via the built-in return mechanism)
// returns a character (via the use of the '&' symbol)
// receives a double along with a variable number of other values

B. Calling Functions
In order for a function to be used, it must be called by another function. To call a function, one enters the name of the function followed by a matching pair of parentheses inside of which is the list of parameter values to be passed to the function in the same order as in the declaration. The parameters included in function declarations are called formal parameters while the parameters listed in a function call are called the actual parameters. The function calling mechanism matches formal and actual parameters simply by order and pays no attention to identifier names. If the types of corresponding parameters do not match or if a standard type conversion is not possible, a syntax error message is generated. An error is also generate if the number of formal and actual arguments do not match - unless the formal parameter list includes an ellipsis.

There are two mechanisms used to pass parameters. When a reference parameter is passed, the memory address of the actual parameter is passed to the function and the formal argument identifier becomes a second symbolic name for the same memory location. This mechanism has the obvious name pass by reference.

The second mechanism is called pass by value. When a parameter (also called an argument) is passed by value, a copy of the information being passed is sent to the calling function and placed in a new memory location set aside for the formal argumment. Thus, any changes to this new memory location have no effect on the value in the memory for the actual parameter in the calling function.

The actual parameter list can include named or unnamed constants (for example, strings or numeric values) and variables. One can also pass other elements such as expressions and pointers to functions - see your manual for more details. Rvalues such as named and unnamed constants as well as complex expressions can passed by reference but nothing will be returned. In the case of constants, this is because the value of a constant cannot be modified. In the case of expressions, there is no specific memory location to modify.

  Discussion of Parameters in "The Story of C++"

C. Function Definitions
The definition for a function contains the instructions the function will execute when called. Definitions start with the function declaration minus the trailing semicolon and must, unlike a function declaration, include identifiers for each of the formal parameters. What follows is the body of the function consisting of an opening and closing pair of braces inside of which are the C++ statements of the function. This represents the block of code for the function. The statements can include declarations and any C++ statement.

If the function has been declared with a return type, the return instruction should be included in every path through the function. If not, one or more warning messages will be generated. The 'return' takes the form:

return some expression;

where 'some expression' is a constant, variable, or some more complex expression representing the value to be returned by the function.

When a function is called, the parameters are passed, the statements in the function body are executed and the function terminates when it either reaches the end of the function body or a return statement is executed. Upon terminination, the memory for all identifiers with local duration is deallocated and the identifiers with local scope become unusable. If the calling function does not include a way for the value returned (if there is one) to be used, that value is ignored.

More on the basics of functions in Chapter 4 of the Story of C++

D. Function Overloading
It is possible for a function identifier with the same name to be declared and defined in multiple ways if each declaration/definition includes different numbers and/or types of parameters. This allows functions with the same name to execute different code as long as the number and/or type of the parameters is different. The system determines which version of the function to call by examining the type and number of the actual parameters. Note that there must be differences in the parameter lists of the two functions and not just in the return types since the return types are not part of the actual parameters.

  Description in "The Story of C++"

E. Inline Functions

Function calls take time. The computer must save where it left off in the calling function, allocate memory for any parameters being passed by value, pass all the parameter values or addresses, and jump to the instructions for the function being called. Upon returning, it must de-allocate memory, perform the built-in return procedure, and jump back to where it left off in the calling function. For reasons that are related to software engineering principles, programs are designed to use function calls even when the calling functions are very small and the overhead takes more time than the actual function body execution. To meet the goals of software engineering while improving efficiency, C++ provides inline functions. For such functions, the calls look just the same but at compile time, the compiler does not generate the code for a function call. Instead, the function body is inserted into the calling function in place of the function call. The programmer sees a function call, the computer at run-time simply sees a few lines of code.

There are two ways to declare a function as 'inline'. In the first way one adds the keyword 'inline' as the first word of a function definition. The second way is used in conjunction with class member functions and is discussed in Section XI.

Links to 'The Story of C++" and other documents

General Discussion of Functions
General Discussion of Parameters
Pass by Value and Pass by Reference
Function Overloading
Default Parameter Values

Top of Section Main Menu of Essentials of C++ Next Section