In C++, names have scope (§ 2.2.4, p. 48), and objects have lifetimes. It is important to understand both of these concepts.
• The scope of a name is the part of the program’s text in which that name is visible.
• The lifetime of an object is the time during the program’s execution that the object exists.
As we’ve seen, the body of a function is a statement block. As usual, the block forms a new scope in which we can define variables. Parameters and variables defined inside a function body are referred to as local variables. They are “local” to that function and hide declarations of the same name made in an outer scope.
Exercise 6.1: What is the difference between a parameter and an argument?
Exercise 6.2: Indicate which of the following functions are in error and why. Suggest how you might correct the problems.
(a) int f() {
string s;
// ...
return s;
}
(b) f2(int i) { /* ... */ }
(c) int calc(int v1, int v1) /* ... */ }
(d) double square(double x) return x * x;
Exercise 6.3: Write and test your own version of fact
.
Exercise 6.4: Write a function that interacts with the user, asking for a number and generating the factorial of that number. Call this function from main
.
Exercise 6.5: Write a function to return the absolute value of its argument.
Objects defined outside any function exist throughout the program’s execution. Such objects are created when the program starts and are not destroyed until the program ends. The lifetime of a local variable depends on how it is defined.
The objects that correspond to ordinary local variables are created when the function’s control path passes through the variable’s definition. They are destroyed when control passes through the end of the block in which the variable is defined. Objects that exist only while a block is executing are known as automatic objects. After execution exits a block, the values of the automatic objects created in that block are undefined.
Parameters are automatic objects. Storage for the parameters is allocated when the function begins. Parameters are defined in the scope of the function body. Hence they are destroyed when the function terminates.
Automatic objects corresponding to the function’s parameters are initialized by the arguments passed to the function. Automatic objects corresponding to local variables are initialized if their definition contains an initializer. Otherwise, they are default initialized (§ 2.2.1, p. 43), which means that uninitialized local variables of built-in type have undefined values.
static
ObjectsIt can be useful to have a local variable whose lifetime continues across calls to the function. We obtain such objects by defining a local variable as static
. Each local static
object is initialized before the first time execution passes through the object’s definition. Local static
s are not destroyed when a function ends; they are destroyed when the program terminates.
As a trivial example, here is a function that counts how many times it is called:
size_t count_calls()
{
static size_t ctr = 0; // value will persist across calls
return ++ctr;
}
int main()
{
for (size_t i = 0; i != 10; ++i)
cout << count_calls() << endl;
return 0;
}
This program will print the numbers from 1 through 10 inclusive.
Before control flows through the definition of ctr
for the first time, ctr
is created and given an initial value of 0
. Each call increments ctr
and returns its new value. Whenever count_calls
is executed, the variable ctr
already exists and has whatever value was in that variable the last time the function exited. Thus, on the second invocation, the value of ctr
is 1
, on the third it is 2
, and so on.
If a local static
has no explicit initializer, it is value initialized (§ 3.3.1, p. 98), meaning that local static
s of built-in type are initialized to zero.
Exercise 6.6: Explain the differences between a parameter, a local variable, and a local static
variable. Give an example of a function in which each might be useful.
Exercise 6.7: Write a function that returns 0 when it is first called and then generates numbers in sequence each time it is called again.