Overview

An object has a storage duration that determines its lifetime. There are four storage durations: static, thread, automatic, and allocated.

Static

An object whose identifier is declared without storage-class specifier _Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration.

Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup. Initialization always happens.

Thread Local

An object whose identifier is declared with the storage-class specified _Thread_local has thread storage duration.

Its lifetime is the entire execution of the thread for which it is created, and its stored value is initialized when the thread is started.

Automatic

An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration, as do some compound literals.

For these objects that do not have a VLA type, its lifetime extends from entry into its enclosing block until execution of that block ends. Its initial value is indeterminate. If initialization is specified, it is performed each time the declaration or compound literal is reached in the execution of the block.

For these objects that do have a VLA type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.

A non-lvalue expression with structure or union type, where the structure or union contains a member with array type refers to an object with automatic storage duration and temporary lifetime. Its lifetime lasts for the duration of the expression evaluation it is found within.

Register

In contrast to auto, there also exists a register storage-class specifier. The & operator is not allowed for variables declared with register meaning variables declared with register can’t alias.

Because of array-to-pointer decay, arrays with storage-class register are useless.

Dynamic Allocation

The <stdlib.h> header provides the two most prominent functions used for managing dynamic memory: malloc and free. The former is used to allocate new memory whereas the latter is used to annihilate it.

void* malloc(size_t size);
void free(void*);

Dynamically allocated objects have allocated storage duration. Their lifetime spans allocation to explicit destruction.

Storage-Class Specifiers

Storage-class specifiers are used to control an object’s storage duration and an identifier’s linkage. There are six storage-class specifiers:

At most, one storage-class specifier may be given in the declaration specifiers in a declaration, except that _Thread_local may appear with static or extern.

Bibliography