Ready to practice?
Sign up to access interactive coding exercises and track your progress.
Scope, duration, and linkage Summary
Review and test your understanding of all scope, duration, and linkage concepts covered in this chapter.
Scope, Duration, and Linkage Summary
Scope, duration, and linkage are fundamental but often confusing concepts. This lesson provides a comprehensive reference summarizing everything, including topics we'll cover later.
Scope Summary
An identifier's scope determines where it can be accessed within source code.
-
Block (local) scope: Variables accessible only from their declaration point until the end of their enclosing block (including nested blocks). This includes:
- Local variables
- Function parameters
- User-defined types (enums, classes) declared inside blocks
-
Global scope: Variables and functions accessible from their declaration point until the end of the file. This includes:
- Global variables
- Functions
- User-defined types (enums, classes) declared inside namespaces or at global scope
Duration Summary
A variable's duration determines when it is created and destroyed.
-
Automatic duration: Variables created at their definition point and destroyed when their block exits. This includes:
- Local variables
- Function parameters
-
Static duration: Variables created when the program begins and destroyed when it ends. This includes:
- Global variables
- Static local variables
-
Dynamic duration: Variables created and destroyed by programmer request. This includes:
- Dynamically allocated variables
Linkage Summary
An identifier's linkage determines whether declarations of the same identifier in different scopes refer to the same entity (object, function, reference, etc.).
Local variables have no linkage. Each declaration of an identifier with no linkage refers to a unique entity.
-
No linkage: Each declaration refers to a unique entity. This includes:
- Local variables
- User-defined type identifiers (enums, classes) declared inside blocks
-
Internal linkage: Declarations of the same identifier within the same translation unit refer to the same object or function. This includes:
- Static global variables (initialized or uninitialized)
- Static functions
- Const global variables
- Unnamed namespaces and their contents
-
External linkage: Declarations of the same identifier anywhere in the program refer to the same object or function. This includes:
- Non-static functions
- Non-const global variables (initialized or uninitialized)
- Extern const global variables
- Inline const global variables
- Namespaces
Identifiers with external linkage generally cause duplicate definition linker errors if compiled into multiple source files (violating the one-definition rule). Exceptions exist for types, templates, and inline functions/variables—we'll cover these in future lessons.
Note that functions have external linkage by default. They can be made internal using static.
Variable Scope, Duration, and Linkage Summary
Variables have all three properties, summarized in this table:
| Type | Example | Scope | Duration | Linkage | Notes |
|---|---|---|---|---|---|
| Local variable | int playerHealth; |
Block | Automatic | None | |
| Static local variable | static int s_sessionID; |
Block | Static | None | |
| Dynamic local variable | int* buffer{ new int{} }; |
Block | Dynamic | None | |
| Function parameter | void processInput(int keyCode) |
Block | Automatic | None | |
| Internal non-const global variable | static int g_gameState; |
Global | Static | Internal | Initialized or uninitialized |
| External non-const global variable | int g_frameCount; |
Global | Static | External | Initialized or uninitialized |
| Inline non-const global variable (C++17) | inline int g_windowWidth; |
Global | Static | External | Initialized or uninitialized |
| Internal constant global variable | constexpr int g_maxPlayers{ 4 }; |
Global | Static | Internal | Must be initialized |
| External constant global variable | extern const int g_serverPort{ 8080 }; |
Global | Static | External | Must be initialized |
| Inline constant global variable (C++17) | inline constexpr int g_tileSize{ 32 }; |
Global | Static | External | Must be initialized |
Forward Declaration Summary
Forward declarations allow accessing functions or variables from other files. The declared variable's scope follows usual rules (global scope for globals, block scope for locals).
| Type | Example | Notes |
|---|---|---|
| Function forward declaration | void renderFrame(int fps); |
Prototype only, no function body |
| Non-constant variable forward declaration | extern int g_windowWidth; |
Must be uninitialized |
| Const variable forward declaration | extern const int g_maxConnections; |
Must be uninitialized |
| Constexpr variable forward declaration | extern constexpr int g_bufferSize; |
Not allowed, constexpr cannot be forward declared |
A constexpr variable (implicitly const) can be forward declared using a const variable forward declaration. When accessed through the forward declaration, it's considered const (not constexpr).
What is a Storage Class Specifier?
When used in identifier declarations, the static and extern keywords are called storage class specifiers. They set the storage duration and linkage of identifiers.
C++ supports four 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 | |
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 compiler to place in register | Deprecated in C++17 |
The term "storage class specifier" appears primarily in formal documentation.
Summary
Scope: Determines where an identifier can be accessed. Block scope (local) is visible from declaration to end of block. Global scope is visible from declaration to end of file.
Duration: Determines when a variable is created and destroyed. Automatic duration (local variables) exists from definition to block exit. Static duration (globals, static locals) exists from program start to program end. Dynamic duration is controlled by programmer.
Linkage: Determines whether declarations of the same identifier refer to the same entity. No linkage means each declaration is independent. Internal linkage means same identifier in different translation units refers to different entities. External linkage means same identifier across the program refers to the same entity.
Variable summary: Local variables have block scope, automatic duration, and no linkage. Global non-const variables have global scope, static duration, and external linkage (or internal with static). Global const variables have global scope, static duration, and internal linkage (or external with extern).
Forward declarations: Allow accessing identifiers from other files. Function forward declarations don't need extern. Non-const and const variable forward declarations use extern without initializer. Constexpr variables cannot be forward declared.
Storage class specifiers: extern and static keywords are storage class specifiers when used in declarations. They set linkage and storage duration.
This comprehensive reference table summarizes the relationships between scope, duration, and linkage for all variable types in C++, serving as a quick lookup for understanding identifier properties.
Scope, duration, and linkage Summary - Quiz
Test your understanding of the lesson.
Practice Exercises
Identify Scope and Linkage
Identify the scope, duration, and linkage of different variable declarations.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!