In C++, objects can be declared with automatic storage class using the auto or register keyword. If no storage-class keyword is used for a local object (an object declared inside a function), auto is assumed. C++ handles initializations and declarations of these objects differently than objects declared with static storage classes.
Each time declaration statements for objects of storage class auto or register are executed, initialization takes place. The following example, from “The continue Statement” shows initialization of the automatic object ch inside the do loop.
// Get a character that is a member of the zero-terminated
// string, szLegalString. Return the index of the character
// entered.
int GetLegalChar( char *szLegalString )
{
char *pch;
do
{
// This declaration statement is executed once for each
// execution of the loop.
char ch = getch();
if( (pch = strchr( szLegalString, ch )) == NULL )
continue;
// A character that was in the string szLegalString
// was entered. Return its index.
return (pch - szLegalString);
} while( 1 );
}
For each iteration of the loop (each time the declaration is encountered), the macro getch is evaluated and ch is initialized with the results. When control is transferred outside the block using the return statement, ch is destroyed (in this case, the storage is deallocated).
See “Storage Classes” in Chapter 2, on topic for another example of initialization.
Objects declared in a loop are destroyed once per iteration of the loop, on exit from the block, or when control transfers to a point prior to the declaration. Objects declared in a block that is not a loop are destroyed on exit from the block, or when control transfers to a point prior to the declaration.
Note :
Destruction can mean simply deallocating the object, or, for class-type objects, invoking the object's destructor.
When a jump statement transfers control out of a loop or block, objects declared in the block transferred from are destroyed; objects in the block transferred to are not destroyed.
When control is transferred to a point prior to a declaration, the object is destroyed.
Using the goto statement or a case label in a switch statement, it is possible to specify a program that branches past an automatic object initializer. Such code is illegal unless the declaration that contains the initializer is in a block enclosed by the block in which the jump statement occurs.
The following example shows a loop that declares and initializes the objects total, ch, and i. There is also an erroneous goto statement that transfers control past an initializer.
// Read input until a nonnumeric character is entered.
while( 1 )
{
int total = 0;
char ch = getch();
if( ch >= '0' || ch <= '9' )
{
goto Label1; // Error: transfers past initialization
// of i.
int i = ch - '0';
Label1:
total += i;
} // i would be destroyed here if the
// goto error were not present.
else
// Break statement transfers control out of loop,
// destroying total and ch.
break;
}
In the above example, the goto statement tries to transfer control past the initialization of i. However, if i were declared but not initialized, the transfer would be legal.
The objects total and ch, declared in the block that serves as the statement of the while statement, are destroyed when that block is exited using the break statement.