Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
When talked about a C++/C
variable, the standard ISO document mentions storage class
, storage duration
, file scope
, lifetime
, and linkage
.
I want to understand the basic clues and how they are related to each other. But after reading the ISO
documents, I cannot find a clear logic map for these concepts.
Could you help clarify it? I hope I can use there concepts to analyze my programming problem.
The ISO documents
sections:
- C99 6.7.1 Storage-class specifiers
- C99 6.11.2 Linkages of identifiers
- C++2003 7.1.1 Storage class specifiers
- C++2003 7.5 Linkage specifications
- etc.
Storage class specifiers are a part of the decl-specifier-seq
of a declaration syntax. They control two independent properties of the names introduced by the declaration: their storage duration and their linkage. Storage class specifiers:
auto
- automatic storage duration (until C++11)
register
- automatic storage duration. Also hints to the compiler to place the variable in the processor's register (deprecated)
static
- static or thread storage duration and internal linkage
extern
- static or thread storage duration and external linkage
thread_local
- thread storage duration (since C++11)
Storage durations:
automatic
storage duration. The variable is allocated at the beginning of the enclosing code block and deallocated on end. All non-global variables have this storage duration, except those declared static
, extern
or thread_local
.
static
storage duration. The variable is allocated when the program begins and deallocated when the program ends. Only one instance of the variable exists. All global variables have this storage duration, plus those declared with static
or extern
.
thread
storage duration. The variable is allocated when the thread begins and deallocated when the thread ends. Each thread has its own instance of the variable. Only variables declared thread_local
have this storage duration. thread_local
can appear together with static
or extern
to adjust linkage.
(since C++11)
dynamic
storage duration. The variable is allocated and deallocated per request by using dynamic memory allocation functions.
Linkage. A name that denotes object, reference, function, type, template, namespace, or value, may have linkage. If a name has linkage, it refers to the same entity as the same name introduced by a declaration in another scope. If a variable, function, or another entity with the same name is declared in several scopes, but does not have sufficient linkage, then several instances of the entity are generated.
The following linkages are recognized:
- No linkage. The name can be referred to only from the scope it is in.
- Internal linkage. The name can be referred to from all scopes in the current translation unit.
- External linkage. The variable can be referred to from the scopes in the other translation units.
Reference.
While I had an intuitive understanding of the notions, I was quite curious about what they truly meant; what the rules were and why they were what they were.
So I wrote a full blog post about it, which is as thorough as it's going to get without being the standard, but is much simpler to understand.
Here are the key insights:
(An object in C is a variable or a function)
The scope of a declaration is the part of the code where the
declaration is seen and can be used.
Note that this says nothing about whether the object associated to the
declaration can be accessed from some other part of the code via
another declaration!
We identify a unique object by its memory: the storage for a variable
or the function code.
Duration indicates whether the object associated to the declaration
persists throughout the program's execution (static duration) or whether it is allocated
dynamically when the declaration's scope is entered (dynamic duration).
Linkage is what determines if multiple declarations of the same object
refer to the same object, or to separate ones.
About Linkage, if we simplify a bit:
- no linkage: the declaration refers to a unique object
- internal linkage: all declarations in a compilation unit refer to the same object
- external linkage: all declarations with external linkage in the program refer to the same object
Finally, a handy rule:
One can determine the linkage and duration of any declaration using
only three rules (most prioritary rule first):
Within functions, declarations without extern
have no linkage.
Within functions, declarations without extern
or static
have automatic duration. Any other declaration, at any scope, has static
duration.
Within a compilation unit, objects have internal linkage if there is a declaration with the static
storage class specifier. This
declaration must happen before any extern
declaration, and there
cannot be any declaration without storage class specifier (or a
compilation error ensues). Otherwise, they have external linkage.
I hope this helps!