Home > Articles > Programming > C/C++

C++ Reference Guide

Hosted by

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Automatic Storage

Last updated Jan 1, 2003.

Storage duration is the property of an object that defines the minimum potential lifetime of the storage (memory category) containing the object. The storage duration is determined by the construct used to create the object, including the storage class specifier(s). The most widely-used storage duration is automatic storage duration. Object that are allocated on the stack memory are said to have automatic storage duration because they are automatically allocated and deallocated. The following objects have automatic storage:

  • Local objects that are not explicitly declared static ,extern or thread_local
  • Local objects that are declared with the auto storage class specifier (in all dialects of C, and in all dialects of C++ except C++09)
  • Objects declared with the register storage class specifier.
  • Function parameters.
  • Temporaries.

Storage Class Specifiers

Do not confuse storage duration with storage class specifiers. The C++09 storage class specifiers are:

  • register
  • static
  • thread_local
  • extern
  • mutable

In pre-C++09 the storage class specifiers list is slightly different:

  • register
  • static
  • auto
  • extern
  • mutable

In C, the storage class specifiers are:

  • register
  • static
  • auto
  • extern

Automatic Storage Duration

The following code listing contains various declarations, objects, and variables with automatic storage duration:

void f(const std::string & s); //storage type of the string object is determined by the caller
void g(register int n); //function parameter and register, hence automatic
int main()
{
 int n;  // automatic because local, non-static, non-extern and non thread_local
 std::string s; // ditto
 register int i;   // register implies automatic
 auto double d;    // automatic. Valid in all C++ dialects but C++09
 g(n); //passing a copy of n; the copy is automatic
f(std::string temp()); // a temporary has automatic storage 
}

Objects with automatic storage duration, or automatic objects for short, are created automatically upon entering a function or a block. They are destroyed and their storage is reclaimed automatically when the function or block in which they are declared exits. Thus, on each entry into a function or a block, a fresh set of its automatic objects is created. The default value of automatic variables and non-class objects is indeterminate. Automatic objects have no linkage; you cannot refer to them from a different translation unit and their visibility is limited to the scope in which they are declared.

The C++09 standard no longer recognizes auto as a storage class specifier. Therefore, you can't use auto in C++09 code to indicate automatic storage duration. Automatic storage duration in C++09 is thus implied from the context. The auto keyword still exists in C++09 but it has changed its meaning so you should be aware that older C and C++ code which uses auto as a storage class will cause compilation errors.

The register Storage Class Specifier

The register storage class specifier shall be applied only to names of objects declared in a block or to function parameters. A declaration of an object with the register specifier suggests that access to the object be as fast as possible. For example, a counter in a deeply-nested loop declared register may be stored in a CPU register instead of memory. Similarly, a class object declared register may be stored in cache memory for faster access. The extent to which such register requests are effective is implementation-defined. Today, register is rarely used in C or C++. Most compilers do not honor user requests for register variables and objects. Instead, compilers make their own register choice. In ISO C, you cannot take the address of a register variable. In C++ you're allowed to do so but taking the address of a register object nullifies the register request (the object is stored in memory anyway). In all other aspects (initialization, lifetime, scope) objects with the register storage class have the same semantics as automatic objects.

The mutable Storage Class Specifier

The mutable specifier on a class data member nullifies a const specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const. In other words, a mutable member is always modifiable even if it's a member of a const object:

struct S
{
 mutable int x;
 int y;
};
const S s;
s.x=0; //OK, mutable member in a const object
s.y=0; //error, y is a member of a const object

The mutable specifier can be applied only to names of class data members and cannot be applied to names declared const or static, neither can it be applied to reference members. For example

class C 
{
 mutable const int* p; // OK, the pointer is mutable, int is const
 mutable int* const q; // ill-formed
 mutable int &r; //error, references cannot be mutable 

};

In the declaration of the member p, the mutable specifier applies to the pointer, whereas const applies to the int to which the pointer is bound. By contrast, the declaration of q is invalid because the pointer itself is declared const and mutable. Similarly, the declaration of the reference variable r is invalid because a reference variable cannot be mutable.