summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Fstorage_duration.html
diff options
context:
space:
mode:
Diffstat (limited to 'devdocs/c/language%2Fstorage_duration.html')
-rw-r--r--devdocs/c/language%2Fstorage_duration.html144
1 files changed, 144 insertions, 0 deletions
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 @@
+ <h1 id="firstHeading" class="firstHeading">Storage-class specifiers</h1> <p>Specify <i>storage duration</i> and <i>linkage</i> of objects and functions:</p>
+<ul>
+<li>
+<code>auto</code> - automatic duration and no linkage </li>
+<li>
+<code>register</code> - automatic duration and no linkage; address of this variable cannot be taken </li>
+<li>
+<code>static</code> - static duration and internal linkage (unless at block scope) </li>
+<li>
+<code>extern</code> - static duration and external linkage (unless already declared internal) </li>
+</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c11">
+<td> <ul><li>
+<span class="t-rev-inl t-until-c23"><span><code>_Thread_local</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>thread_local</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> - thread storage duration </li></ul> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td>
+</tr> </table> <h3 id="Explanation"> Explanation</h3> <p>Storage-class specifiers appear in <a href="declarations" title="c/language/declarations">declarations</a><span class="t-rev-inl t-since-c23"><span> and <a href="compound_literal" title="c/language/compound literal">compound literal</a> expressions</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>. At most one specifier may be used<span class="t-rev-inl t-since-c11"><span>, except that <span class="t-rev-inl t-until-c23"><span>_Thread_local</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><a href="http://en.cppreference.com/w/c/thread/thread_local"><span class="kw1032">thread_local</span></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> may be combined with <span class="kw4">static</span> or <span class="kw2">extern</span> to adjust linkage</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span>. The storage-class specifiers determine two independent properties of the names they declare: <i>storage duration</i> and <i>linkage</i>.</p>
+<div class="t-li1">
+<span class="t-li">1)</span> The <span class="kw4">auto</span> 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.</div> <div class="t-li1">
+<span class="t-li">2)</span> The <span class="kw4">register</span> 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 <span class="kw4">register</span> cannot be used as arguments to the <a href="operator_member_access" title="c/language/operator member access">address-of operator</a><span class="t-rev-inl t-since-c11"><span>, cannot use <a href="_alignas" title="c/language/ Alignas">alignas</a></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span>, and <span class="kw4">register</span> arrays are not convertible to pointers.</div> <div class="t-li1">
+<span class="t-li">3)</span> The <span class="kw4">static</span> specifier specifies both static storage duration<span class="t-rev-inl t-since-c11"><span> (unless combined with _Thread_local)</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> 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.</div> <div class="t-li1">
+<span class="t-li">4)</span> The <span class="kw2">extern</span> specifier specifies static storage duration<span class="t-rev-inl t-since-c11"><span> (unless combined with <span class="t-rev-inl t-until-c23"><span>_Thread_local</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><a href="http://en.cppreference.com/w/c/thread/thread_local"><span class="kw1032">thread_local</span></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>)</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> and external linkage. It can be used with function and object declarations in both file and block scope (excluding function parameter lists). If <span class="kw2">extern</span> 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.</div> <table class="t-rev-begin"> <tr class="t-rev t-since-c11">
+<td> <span class="t-li">5)</span> <span class="t-rev-inl t-until-c23"><span>_Thread_local</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><a href="http://en.cppreference.com/w/c/thread/thread_local"><span class="kw1032">thread_local</span></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> indicates <i>thread storage duration</i>. 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 <span class="kw4">static</span> or <span class="kw2">extern</span> to decide linkage. </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td>
+</tr> </table> <p>If no storage-class specifier is provided, the defaults are:</p>
+<dl>
+<dd> <span class="kw2">extern</span> for all functions </dd>
+<dd> <span class="kw2">extern</span> for objects at file scope </dd>
+<dd> <span class="kw4">auto</span> for objects at block scope </dd>
+</dl> <p>For any struct or union declared with a storage-class specifier, the storage duration (but not linkage) applies to their members, recursively.</p>
+<p>Function declarations at block scope can use <span class="kw2">extern</span> or none at all. Function declarations at file scope can use <span class="kw2">extern</span> or <span class="kw4">static</span>.</p>
+<p>Function parameters cannot use any storage-class specifiers other than <span class="kw4">register</span>. Note that <span class="kw4">static</span> has special meaning in function parameters of array type.</p>
+<h3 id="Storage_duration"> Storage duration</h3> <p>Every <a href="object" title="c/language/object">object</a> has a property called <i>storage duration</i>, which limits the object <a href="lifetime" title="c/language/lifetime">lifetime</a>. There are four kinds of storage duration in C:</p>
+<ul>
+<li>
+<i><b>automatic</b></i> storage duration. The storage is allocated when the <a href="statements#Compound_statements" title="c/language/statements">block</a> in which the object was declared is entered and deallocated when it is exited by any means (<a href="goto" title="c/language/goto">goto</a>, <a href="return" title="c/language/return">return</a>, reaching the end). <span class="t-rev-inl t-since-c99"><span>One exception is the <a href="array#Variable-length_arrays" title="c/language/array">VLAs</a>; their storage is allocated when the declaration is executed, not on block entry, and deallocated when the declaration goes out of scope, not when the block is exited</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>. If the block is entered recursively, a new allocation is performed for every recursion level. All function parameters and non-<span class="kw4">static</span> block-scope objects have this storage duration, <span class="t-rev-inl t-until-c23"><span>as well as <a href="compound_literal" title="c/language/compound literal">compound literals</a> used at block scope</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span> </li>
+<li>
+<i><b>static</b></i> storage duration. The storage duration is the entire execution of the program, and the value stored in the object is initialized only once, prior to <a href="main_function" title="c/language/main function">main function</a>. All objects declared <span class="kw4">static</span> and all objects with either internal or external linkage<span class="t-rev-inl t-since-c11"><span> that aren't declared <span class="t-rev-inl t-until-c23"><span>_Thread_local</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><a href="http://en.cppreference.com/w/c/thread/thread_local"><span class="kw1032">thread_local</span></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> have this storage duration. </li>
+</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c11">
+<td> <ul><li>
+<i><b>thread</b></i> 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 <span class="t-rev-inl t-until-c23"><span>_Thread_local</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><a href="http://en.cppreference.com/w/c/thread/thread_local"><span class="kw1032">thread_local</span></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> have this storage duration. </li></ul> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td>
+</tr> </table> <ul><li>
+<i><b>allocated</b></i> storage duration. The storage is allocated and deallocated on request, using <a href="../memory" title="c/memory">dynamic memory allocation</a> functions. </li></ul> <h4 id="Linkage"> Linkage</h4> <p>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:</p>
+<ul>
+<li>
+<i><b>no linkage</b></i>. The identifier can be referred to only from the scope it is in. All function parameters and all non-<span class="kw2">extern</span> block-scope variables (including the ones declared <span class="kw4">static</span>) have this linkage. </li>
+<ul>
+<li>
+<i><b>internal linkage</b></i>. The identifier can be referred to from all scopes in the current translation unit. All <span class="kw4">static</span> file-scope identifiers (both functions and variables) have this linkage. </li>
+<li>
+<i><b>external linkage</b></i>. The identifier can be referred to from any other translation units in the entire program. All non-<span class="kw4">static</span> functions, all <span class="kw2">extern</span> variables (unless earlier declared <span class="kw4">static</span>), and all file-scope non-<span class="kw4">static</span> variables have this linkage. </li>
+</ul>
+</ul> <p>If the same identifier appears with both internal and external linkage in the same translation unit, the behavior is undefined. This is possible when <a href="extern" title="c/language/extern">tentative definitions</a> are used.</p>
+<h4 id="Linkage_and_libraries"> Linkage and libraries</h4> <p>Declarations with external linkage are commonly made available in header files so that all translation units that <a href="../preprocessor/include" title="c/preprocessor/include">#include</a> the file may refer to the same identifier that are defined elsewhere.</p>
+<p>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.</p>
+<table class="t-rev-begin"> <tr class="t-rev">
+<td> <p>Library interface, header file "flib.h":</p>
+<div class="c source-c"><pre data-language="c">#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</pre></div> <p>Library implementation, source file "flib.c":</p>
+<div class="c source-c"><pre data-language="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)</pre></div> <p>Application code, source file "main.c":</p>
+<div class="c source-c"><pre data-language="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
+}</pre></div> </td> <td></td>
+</tr> </table> <h3 id="Keywords"> Keywords</h3> <p><a href="../keyword/auto" title="c/keyword/auto"><code>auto</code></a>, <a href="../keyword/register" title="c/keyword/register"><code>register</code></a>, <a href="../keyword/static" title="c/keyword/static"><code>static</code></a>, <a href="../keyword/extern" title="c/keyword/extern"><code>extern</code></a>, <a href="../keyword/_thread_local" title="c/keyword/ Thread local"><code>_Thread_local</code></a> <a href="../keyword/thread_local" title="c/keyword/thread local"><code>thread_local</code></a></p>
+<h3 id="Notes"> Notes</h3> <table class="t-rev-begin"> <tr class="t-rev t-until-c23">
+<td> <p>The keyword _Thread_local is usually used through the convenience macro <code><a href="../thread/thread_local" title="c/thread/thread local">thread_local</a></code>, defined in the header <a href="../thread" title="c/thread"><code>&lt;threads.h&gt;</code></a>.</p>
+</td> <td><span class="t-mark-rev t-until-c23">(until C23)</span></td>
+</tr> </table> <p>The <a href="typedef" title="c/language/typedef"><code>typedef</code></a><span class="t-rev-inl t-since-c23"><span> and <a href="constexpr" title="c/language/constexpr"><code>constexpr</code></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> specifiers are formally listed as storage-class specifiers in the C language grammar, but do not specify storage.</p>
+<table class="t-rev-begin"> <tr class="t-rev t-since-c23">
+<td> <p>The auto specifier is also used for type inference.</p>
+</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td>
+</tr> </table> <p>Names at file scope that are <span class="kw4">const</span> and not <span class="kw2">extern</span> have external linkage in C (as the default for all file-scope declarations), but internal linkage in C++.</p>
+<h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+
+// static storage duration
+int A;
+
+int main(void)
+{
+ printf("&amp;A = %p\n", (void*)&amp;A);
+
+ // automatic storage duration
+ int A = 1; // hides global A
+ printf("&amp;A = %p\n", (void*)&amp;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
+}</pre></div> <p>Possible output:</p>
+<div class="text source-text"><pre data-language="c">&amp;A = 0x600ae4
+&amp;A = 0x7ffefb064f5c
+address of int in allocated memory = 0x1f28c30</pre></div> </div> <h3 id="References"> References</h3> <ul>
+<li> C23 standard (ISO/IEC 9899:2023): </li>
+<ul>
+<li> 6.2.2 Linkages of identifiers (p: 35-36) </li>
+<li> 6.2.4 Storage durations of objects (p: 36-37) </li>
+<li> 6.7.1 Storage-class specifiers (p: 97-100) </li>
+</ul>
+<li> C17 standard (ISO/IEC 9899:2018): </li>
+<ul>
+<li> 6.2.2 Linkages of identifiers (p: 29-30) </li>
+<li> 6.2.4 Storage durations of objects (p: 30) </li>
+<li> 6.7.1 Storage-class specifiers (p: 79) </li>
+</ul>
+<li> C11 standard (ISO/IEC 9899:2011): </li>
+<ul>
+<li> 6.2.2 Linkages of identifiers (p: 36-37) </li>
+<li> 6.2.4 Storage durations of objects (p: 38-39) </li>
+<li> 6.7.1 Storage-class specifiers (p: 109-110) </li>
+</ul>
+<li> C99 standard (ISO/IEC 9899:1999): </li>
+<ul>
+<li> 6.2.2 Linkages of identifiers (p: 30-31) </li>
+<li> 6.2.4 Storage durations of objects (p: 32) </li>
+<li> 6.7.1 Storage-class specifiers (p: 98-99) </li>
+</ul>
+<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
+<ul>
+<li> 3.1.2.2 Linkages of identifiers </li>
+<li> 3.1.2.4 Storage durations of objects </li>
+<li> 3.5.1 Storage-class specifiers </li>
+</ul>
+</ul> <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/storage_duration" title="cpp/language/storage duration">C++ documentation</a></span> for <span class=""><span>Storage class specifiers</span></span> </td>
+</tr> </table> <div class="_attribution">
+ <p class="_attribution-p">
+ &copy; cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
+ <a href="https://en.cppreference.com/w/c/language/storage_duration" class="_attribution-link">https://en.cppreference.com/w/c/language/storage_duration</a>
+ </p>
+</div>