From 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 7 Apr 2024 13:41:34 -0500 Subject: new repository --- devdocs/c/language%2Fstorage_duration.html | 144 +++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 devdocs/c/language%2Fstorage_duration.html (limited to 'devdocs/c/language%2Fstorage_duration.html') diff --git a/devdocs/c/language%2Fstorage_duration.html b/devdocs/c/language%2Fstorage_duration.html new file mode 100644 index 00000000..558ffa50 --- /dev/null +++ b/devdocs/c/language%2Fstorage_duration.html @@ -0,0 +1,144 @@ +

Storage-class specifiers

Specify storage duration and linkage of objects and functions:

+ + +
  • +_Thread_local(until C23)thread_local(since C23) - thread storage duration
(since C11)

Explanation

Storage-class specifiers appear in declarations and compound literal expressions(since C23). At most one specifier may be used, except that _Thread_local(until C23)thread_local(since C23) may be combined with static or extern to adjust linkage(since C11). The storage-class specifiers determine two independent properties of the names they declare: storage duration and linkage.

+
+1) The auto specifier is only allowed for objects declared at block scope (except function parameter lists). It indicates automatic storage duration and no linkage, which are the defaults for these kinds of declarations.
+2) The register specifier is only allowed for objects declared at block scope, including function parameter lists. It indicates automatic storage duration and no linkage (which is the default for these kinds of declarations), but additionally hints the optimizer to store the value of this variable in a CPU register if possible. Regardless of whether this optimization takes place or not, variables declared register cannot be used as arguments to the address-of operator, cannot use alignas(since C11), and register arrays are not convertible to pointers.
+3) The static specifier specifies both static storage duration (unless combined with _Thread_local)(since C11) and internal linkage (unless used at block scope). It can be used with functions at file scope and with variables at both file and block scope, but not in function parameter lists.
+4) The extern specifier specifies static storage duration (unless combined with _Thread_local(until C23)thread_local(since C23))(since C11) and external linkage. It can be used with function and object declarations in both file and block scope (excluding function parameter lists). If extern appears on a redeclaration of an identifier that was already declared with internal linkage, the linkage remains internal. Otherwise (if the prior declaration was external, no-linkage, or is not in scope), the linkage is external.
+ +
5) _Thread_local(until C23)thread_local(since C23) indicates thread storage duration. It cannot be used with function declarations. If it is used on a declaration of an object, it must be present on every declaration of the same object. If it is used on a block-scope declaration, it must be combined with either static or extern to decide linkage. (since C11)

If no storage-class specifier is provided, the defaults are:

+
+
extern for all functions
+
extern for objects at file scope
+
auto for objects at block scope
+

For any struct or union declared with a storage-class specifier, the storage duration (but not linkage) applies to their members, recursively.

+

Function declarations at block scope can use extern or none at all. Function declarations at file scope can use extern or static.

+

Function parameters cannot use any storage-class specifiers other than register. Note that static has special meaning in function parameters of array type.

+

Storage duration

Every object has a property called storage duration, which limits the object lifetime. There are four kinds of storage duration in C:

+ + +
  • +thread storage duration. The storage duration is the entire execution of the thread in which it was created, and the value stored in the object is initialized when the thread is started. Each thread has its own, distinct, object. If the thread that executes the expression that accesses this object is not the thread that executed its initialization, the behavior is implementation-defined. All objects declared _Thread_local(until C23)thread_local(since C23) have this storage duration.
(since C11)

Linkage

Linkage refers to the ability of an identifier (variable or function) to be referred to in other scopes. If a variable or function with the same identifier is declared in several scopes, but cannot be referred to from all of them, then several instances of the variable are generated. The following linkages are recognized:

+

If the same identifier appears with both internal and external linkage in the same translation unit, the behavior is undefined. This is possible when tentative definitions are used.

+

Linkage and libraries

Declarations with external linkage are commonly made available in header files so that all translation units that #include the file may refer to the same identifier that are defined elsewhere.

+

Any declaration with internal linkage that appears in a header file results in a separate and distinct object in each translation unit that includes that file.

+ + +

Library interface, header file "flib.h":

+
#ifndef FLIB_H
+#define FLIB_H
+void f(void);              // function declaration with external linkage
+extern int state;          // variable declaration with external linkage
+static const int size = 5; // definition of a read-only variable with internal linkage
+enum { MAX = 10 };         // constant definition
+inline int sum (int a, int b) { return a + b; } // inline function definition
+#endif // FLIB_H

Library implementation, source file "flib.c":

+
#include "flib.h"
+ 
+static void local_f(int s) {} // definition with internal linkage (only used in this file)
+static int local_state;       // definition with internal linkage (only used in this file)
+ 
+int state;                       // definition with external linkage (used by main.c)
+void f(void) { local_f(state); } // definition with external linkage (used by main.c)

Application code, source file "main.c":

+
#include "flib.h"
+ 
+int main(void)
+{
+    int x[MAX] = {size}; // uses the constant and the read-only variable
+    state = 7;           // modifies state in flib.c
+    f();                 // calls f() in flib.c
+}

Keywords

auto, register, static, extern, _Thread_local thread_local

+

Notes

+ +

The keyword _Thread_local is usually used through the convenience macro thread_local, defined in the header <threads.h>.

+
(until C23)

The typedef and constexpr(since C23) specifiers are formally listed as storage-class specifiers in the C language grammar, but do not specify storage.

+ + +

The auto specifier is also used for type inference.

+
(since C23)

Names at file scope that are const and not extern have external linkage in C (as the default for all file-scope declarations), but internal linkage in C++.

+

Example

#include <stdio.h>
+#include <stdlib.h>
+ 
+// static storage duration
+int A;
+ 
+int main(void)
+{
+    printf("&A = %p\n", (void*)&A);
+ 
+    // automatic storage duration
+    int A = 1;   // hides global A
+    printf("&A = %p\n", (void*)&A);
+ 
+    // allocated storage duration
+    int* ptr_1 = malloc(sizeof(int));   // start allocated storage duration
+    printf("address of int in allocated memory = %p\n", (void*)ptr_1);
+    free(ptr_1);                        // stop allocated storage duration
+}

Possible output:

+
&A = 0x600ae4
+&A = 0x7ffefb064f5c
+address of int in allocated memory = 0x1f28c30

References

See also

+
C++ documentation for Storage class specifiers
+

+ © cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
+ https://en.cppreference.com/w/c/language/storage_duration +

+
-- cgit v1.2.3