- Learn C++ - https://www.learncpp.com -

6.11 — Scope, duration, and linkage summary

The concepts of scope, duration, and linkage cause a lot of confusion, so we’re going to take an extra lesson to summarize everything. Some of these things we haven’t covered yet, and they’re here just for completeness / reference later.

Scope summary

An identifier’s scope determines where the identifier can be accessed within the source code.

Duration summary

A variable’s duration determines when it is created and destroyed.

Linkage summary

An identifier’s linkage determines whether multiple declarations of an identifier refer to the same identifier or not.

Identifiers with external linkage will generally cause a duplicate definition linker error if the definitions are compiled into more than one .cpp file (due to violating the one-definition rule). There are some exceptions to this rule (for types, templates, and inline functions and variables) -- we’ll cover these further in future lessons when we talk about those topics.

Also note that functions have external linkage by default. They can be made internal by using the static keyword.

Variable scope, duration, and linkage summary

Because variables have scope, duration, and linkage, let’s summarize in a chart:

Type Example Scope Duration Linkage Notes
Local variable int x; Block Automatic None
Static local variable static int s_x; Block Static None
Dynamic variable int *x { new int{} }; Block Dynamic None
Function parameter void foo(int x) Block Automatic None
External non-constant global variable int g_x; File Static External Initialized or uninitialized
Internal non-constant global variable static int g_x; File Static Internal Initialized or uninitialized
Internal constant global variable constexpr int g_x { 1 }; File Static Internal Must be initialized
External constant global variable extern constexpr int g_x { 1 }; File Static External Must be initialized
Inline constant global variable inline constexpr int g_x { 1 }; File Static External Must be initialized
Internal constant global variable const int g_x { 1 }; File Static Internal Must be initialized
External constant global variable extern const int g_x { 1 }; File Static External Must be initialized at definition
Inline constant global variable inline const int g_x { 1 }; File Static External Must be initialized

Forward declaration summary

You can use a forward declaration to access a function or variable in another file:

Type Example Notes
Function forward declaration void foo(int x); Prototype only, no function body
Non-constant global variable forward declaration extern int g_x; Must be uninitialized
Const global variable forward declaration extern const int g_x; Must be uninitialized
Constexpr global variable forward declaration extern constexpr int g_x; Not allowed, constexpr cannot be forward declared

What the heck is a storage class specifier?

When used as part of an identifier declaration, the static and extern keywords are called storage class specifiers. In this context, they set the storage duration and linkage of the identifier.

C++ supports 4 active storage class specifiers:

Specifier Meaning Note
extern static (or thread_local) storage duration and external linkage
static static (or thread_local) storage duration and internal linkage
thread_local thread storage duration Introduced in C++11
mutable object allowed to be modified even if containing class is const
auto automatic storage duration Deprecated in C++11
register automatic storage duration and hint to the compiler to place in a register Deprecated in C++17

The term storage class specifier is typically only used in formal documentation.


6.12 -- Using statements [1]
Index [2]
6.10 -- Static local variables [3]