Functions (C++)

Inline Functions
Implementing a program as a set of functions is good from a software engineering standpoint, but function calls involve execution-time overhead. C++ provides //inline functions// to help reduce function call overhead, especially for small functions. They "advises" the compiler to generate a copy of the function's body code in place (when appropriate) to avoid a function call. The trade-off is that multiple copies of the function code are inserted in the program (often making the program larger). The compiler can ignore the inline qualifier and typically does so for all but the smallest functions.

A function can be defined to be inline. For example:

The inline specifier is a hint to the compiler that it should attempt to generate code from a call of fac inline rather than laying down the code for the function once and then calling through the usual function call mechanism.

Static Variables
A local variable is initialized when the thread of execution reaches its definition. By default, this happens in every call of the function and each invocation of the function has its own copy of the variable. If a local variable is declared static, a single, statically allocated object will be used to represent that variable in all calls of the function. It will be initialized only the first time the thread of execution reaches its definition. For example:

A static variable provides a function with "a memory" without introducing a global variable that might be accessed and corrupted by other functions. You can use it to record the number of times a function has been called. You can also use it to prevent a variable from being reinitialized inside a loop.

Argument Passing
Consider:

When f is called, val++ increments a local copy of the first actual argument, whereas ref++ increments the second actual argument.

will increment j, but not i. The first argument is passed by //value//, the second argument is passed by //reference//. Functions that modify call-by-reference arguments can make programs hard to read and should most often be avoided. It can, however, be noticeably more efficient to pass a large object by reference than to pass it by value. In that case, the argument might be declared const to indicate that the reference is used for efficiency reasons only and not to enable the called function ot change the value of the object:

The absence of const in the declaration of a reference argument is taken as a statement of intent to modify the variable:

Similarly, declaring a pointer argument const tells readers that the value of an object pointed to by that argument is not changed by the function. For example:

Array Arguments
If an array is used as a function argument, a pointer to its initial element is passed. For example:

That is, an argument of type T[] will be converted to a T* when passed as an argument. They differ from other types in that an array is not (and cannot be) passed by value.

The size of an array is not available to the called function, but there are several ways of circumventing this problem. C-style strings are zero-terminated, so their size can be computed easily. For other arrays, a second argument specifying the size can be passed. For example:

Alternatively, a type such as vector can be used instead of an array.

Default Arguments
It's common for a program to invoke a function repqatedly with the same argument value for a partiular parameter. In such cases, you can specify that such a parameter has a //default argument//. When a progrma omits an argument for a parameter with a default argument in a function call, the compiler rewrites the function call and inserts the default value of that argument.

Default arguments must be the rightmost arguments in a function's parameter list. When calling a function with two or more default arguments, if an omitted argument is not the rightmost argument in the argument list, then all arguments to the right of that argument also must be omitted. For example:

Value Return
Functions can be declared to return a reference type. There are two reasons to make such a declaration:
 * The information being returned is a large enough object that returning a reference is more efficient than returning a copy. What do I mean by "big"? Anything larger than a couple of words. - Stroustup's FAQ
 * The type of the function must be an l-value. most overloaded operators fall into this category, particularly the assignment operator.

A void function cannot return a value. However, a call of a void function doesn't yield a value, so a void function can use a call of a void function as the expression in a return statement. For example:

This form of return is important when writing template functions where the return type is a template parameter.