liveBook · Manning

Storage duration

As explained in Modern C, Third Edition

Storage duration is the lifetime category that determines when a C object is created, exists, and is initialized or destroyed.

In `main`, a local `unsigned i` can hide a file-scope `unsigned i`. An inner `extern unsigned i` names the file-scope object again; it does not create a third object. The example separates two questions: which identifier is visible here, and how long does its object exist? section 13.2

Listing 13.2 An example of shadowing with an extern variable
#include <stdio.h> 1 

unsigned i = 1;        

int main(void) { 2 
  unsigned i = 2;        /* A new object */
  if (i) {            3 
    extern unsigned i;   /* An existing object */ 
    printf("%u\n", i);  /* prints 1 */
  } else {
    printf("%u\n", i);  /* prints 2 */
  }
}

Follow the three declarations of `i`: the local definition creates a distinct object, while the inner `extern` declaration refers to the file-scope object and prints `1`. section 13.2

Storage duration describes when an object's storage exists. A file-scope object has static storage duration and lasts for the whole execution. Calls to a function, including recursive calls, have separate instances of their local variables. Dynamically allocated storage requires explicit tracking and can be freed. Do not infer an object's duration from whether its name is currently visible: a pointer can still designate an object whose identifier is shadowed. section 13.0 section 13.2 section 13.6

Table 13.1 Storage classes, scope, linkage of identifiers, and storage duration of the associated objects. Tentative indicates that a definition is implied only if there is no other definition with an initializer. Induced indicates that the linkage is internal if another declaration with internal linkage has been met prior to that declaration; otherwise, it is external. Compound literals follow similar rules with respect to the block in which they occur, if any.
Class Scope Definition Linkage Duration Lifetime
Initialized File Yes External Static Whole execution
extern, initialized File Yes External Static Whole execution
String literal Any Yes N/A Static Whole execution
static, initialized Any Yes Internal Static Whole execution
constexpr Any Yes Internal Static Whole execution
Uninitialized File Tentative External Static Whole execution
extern, uninitialized Any No Induced Static Whole execution
static, uninitialized Any Tentative Internal Static Whole execution
thread_local File Yes External Thread Whole thread
extern thread_local Any No External Thread Whole thread
static thread_local Any Yes internal Thread Whole thread
Non-VLA None
Non-VLA, auto Block Yes None Automatic Block of definition
register None
VLA Block Yes None Automatic From definition to
end of block
Function return Block Yes None Automatic To the end of
with array expression

Use the table to compare declarations by storage class, scope, linkage, duration, and lifetime rather than treating those properties as interchangeable. section 13.2

TAKEAWAY: Storage duration affects initialization. Static and thread-storage-duration objects receive default initialization; automatic and allocated objects need an explicit initialization strategy. An initializer can establish a variable's state when it becomes visible. For dynamically allocated data, a type-specific initialization function can keep allocation and initialization together; `calloc` is suitable only when an all-bits-zero representation is a valid initialization for the data involved. section 13.4

How Modern C, Third Edition covers it

How deep it goes
Compares declaration properties and initialization rules, with worked shadowing examples and a storage-class table.
Examples
Traces shadowed local and `extern` declarations, then uses allocated rational-number objects to illustrate initialization functions.
What it assumes
Assumes familiarity with C declarations and function calls while distinguishing storage instances from objects.
What you can do after
Diagnose/debug with it by separating name visibility from object lifetime and choosing initialization appropriate to storage duration.
How it connects
Connects object lifetime with scope, shadowing, linkage, dynamic allocation, and initialization.

Also explained in

Compare how 2 books explain storage duration →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.