summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Fextern.html
diff options
context:
space:
mode:
Diffstat (limited to 'devdocs/c/language%2Fextern.html')
-rw-r--r--devdocs/c/language%2Fextern.html56
1 files changed, 56 insertions, 0 deletions
diff --git a/devdocs/c/language%2Fextern.html b/devdocs/c/language%2Fextern.html
new file mode 100644
index 00000000..f2fd53ea
--- /dev/null
+++ b/devdocs/c/language%2Fextern.html
@@ -0,0 +1,56 @@
+ <h1 id="firstHeading" class="firstHeading">External and tentative definitions</h1> <p>At the top level of a <a href="translation_phases" title="c/language/translation phases">translation unit</a> (that is, a source file with all the #includes after the preprocessor), every C program is a sequence of <a href="declarations" title="c/language/declarations">declarations</a>, which declare functions and objects with <a href="storage_duration" title="c/language/storage duration">external or internal linkage</a>. These declarations are known as <i>external declarations</i> because they appear outside of any function.</p>
+<div class="c source-c"><pre data-language="c">extern int n; // external declaration with external linkage
+int b = 1; // external definition with external linkage
+static const char *c = "abc"; // external definition with internal linkage
+int f(void) { // external definition with external linkage
+ int a = 1; // non-external
+ return b;
+}
+static void x(void) { // external definition with internal linkage
+}</pre></div> <p>Objects declared with an external declaration have static <a href="storage_duration" title="c/language/storage duration">storage duration</a>, and as such cannot use <code>auto</code> or <code>register</code> specifiers <span class="t-rev-inl t-since-c23"><span>except that <code>auto</code> can be used for type inference</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>. The identifiers introduced by external declarations have <a href="scope" title="c/language/scope">file scope</a>.</p>
+<h3 id="Tentative_definitions"> Tentative definitions</h3> <p>A <i>tentative definition</i> is an external declaration without an initializer, and either without a <a href="storage_duration" title="c/language/storage duration">storage-class specifier</a> or with the specifier <code>static</code>.</p>
+<p>A <i>tentative definition</i> is a declaration that may or may not act as a definition. If an actual external definition is found earlier or later in the same translation unit, then the tentative definition just acts as a declaration.</p>
+<div class="c source-c"><pre data-language="c">int i1 = 1; // definition, external linkage
+int i1; // tentative definition, acts as declaration because i1 is defined
+extern int i1; // declaration, refers to the earlier definition
+
+extern int i2 = 3; // definition, external linkage
+int i2; // tentative definition, acts as declaration because i2 is defined
+extern int i2; // declaration, refers to the external linkage definition</pre></div> <p>If there are no definitions in the same translation unit, then the tentative definition acts as an actual definition that <a href="initialization#Empty_initialization" title="c/language/initialization">empty-initializes</a> the object.</p>
+<div class="c source-c"><pre data-language="c">int i3; // tentative definition, external linkage
+int i3; // tentative definition, external linkage
+extern int i3; // declaration, external linkage
+// in this translation unit, i3 is defined as if by "int i3 = 0;"</pre></div> <p>Unlike the <a href="storage_duration" title="c/language/storage duration">extern</a> declarations, which don't change the linkage of an identifier if a previous declaration established it, tentative definitions may disagree in linkage with another declaration of the same identifier. If two declarations for the same identifier are in scope and have different linkage, the behavior is undefined:</p>
+<div class="c source-c"><pre data-language="c">static int i4 = 2; // definition, internal linkage
+int i4; // Undefined behavior: linkage disagreement with previous line
+extern int i4; // declaration, refers to the internal linkage definition
+
+static int i5; // tentative definition, internal linkage
+int i5; // Undefined behavior: linkage disagreement with previous line
+extern int i5; // refers to previous, whose linkage is internal</pre></div> <p>A tentative definition with internal linkage must have complete type.</p>
+<div class="c source-c"><pre data-language="c">static int i[]; // Error, incomplete type in a static tentative definition
+int i[]; // OK, equivalent to int i[1] = {0}; unless redeclared later in this file</pre></div> <h3 id="One_definition_rule"> One definition rule</h3> <p>Each translation unit may have zero or one external definition of every identifier with <a href="storage_duration" title="c/language/storage duration">internal linkage</a> (a <code>static</code> global).</p>
+<p>If an identifier with internal linkage is used in any expression other than a <span class="t-rev-inl t-since-c99"><span>non-VLA,</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> <a href="sizeof" title="c/language/sizeof"><code>sizeof</code></a><span class="t-rev-inl t-since-c11"><span>, <a href="_alignof" title="c/language/ Alignof"><code>_Alignof</code></a></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span><span class="t-rev-inl t-since-c23"><span>, or <a href="typeof" title="c/language/typeof"><code>typeof</code></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>, there must be one and only one external definition for that identifier in the translation unit.</p>
+<p>The entire program may have zero or one external definition of every identifier with <a href="storage_duration" title="c/language/storage duration">external linkage</a>.</p>
+<p>If an identifier with external linkage is used in any expression other than a <span class="t-rev-inl t-since-c99"><span>non-VLA,</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> <a href="sizeof" title="c/language/sizeof"><code>sizeof</code></a><span class="t-rev-inl t-since-c11"><span>, <a href="_alignof" title="c/language/ Alignof"><code>_Alignof</code></a></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span><span class="t-rev-inl t-since-c23"><span>, or <a href="typeof" title="c/language/typeof"><code>typeof</code></a></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>, there must be one and only one external definition for that identifier somewhere in the entire program.</p>
+<h3 id="Notes"> Notes</h3> <table class="t-rev-begin"> <tr class="t-rev t-since-c99">
+<td> <p>Inline definitions in different translation units are not constrained by one definition rule. See <a href="inline" title="c/language/inline"><code>inline</code></a> for the details on the inline function definitions.</p>
+</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td>
+</tr> </table> <p>See <a href="storage_duration" title="c/language/storage duration">storage duration and linkage</a> for the meaning of the keyword <code>extern</code> with declarations at file scope</p>
+<p>See <a href="declarations#Definitions" title="c/language/declarations">definitions</a> for the distinction between declarations and definitions.</p>
+<p>Tentative definitions were invented to standardize various pre-C89 approaches to forward declaring identifiers with internal linkage.</p>
+<h3 id="References"> References</h3> <ul>
+<li> C17 standard (ISO/IEC 9899:2018): </li>
+<ul><li> 6.9 External definitions (p: 113-116) </li></ul>
+<li> C11 standard (ISO/IEC 9899:2011): </li>
+<ul><li> 6.9 External definitions (p: 155-159) </li></ul>
+<li> C99 standard (ISO/IEC 9899:1999): </li>
+<ul><li> 6.9 External definitions (p: 140-144) </li></ul>
+<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
+<ul><li> 3.7 EXTERNAL DEFINITIONS </li></ul>
+</ul> <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/extern" class="_attribution-link">https://en.cppreference.com/w/c/language/extern</a>
+ </p>
+</div>