summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Fname_space.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/language%2Fname_space.html
new repository
Diffstat (limited to 'devdocs/c/language%2Fname_space.html')
-rw-r--r--devdocs/c/language%2Fname_space.html74
1 files changed, 74 insertions, 0 deletions
diff --git a/devdocs/c/language%2Fname_space.html b/devdocs/c/language%2Fname_space.html
new file mode 100644
index 00000000..46652601
--- /dev/null
+++ b/devdocs/c/language%2Fname_space.html
@@ -0,0 +1,74 @@
+ <h1 id="firstHeading" class="firstHeading">Lookup and name spaces</h1> <p>When an <a href="identifier" title="c/language/identifier">identifier</a> is encountered in a C program, a lookup is performed to locate the <a href="declarations" title="c/language/declarations">declaration</a> that introduced that identifier and that is currently <a href="scope" title="c/language/scope">in scope</a>. C allows more than one declaration for the same identifier to be in scope simultaneously if these identifiers belong to different categories, called <i>name spaces</i>:</p>
+<div class="t-li1">
+<span class="t-li">1)</span> Label name space: all identifiers declared as <a href="statements#Labels" title="c/language/statements">labels</a>.</div> <div class="t-li1">
+<span class="t-li">2)</span> Tag names: all identifiers declared as names of <a href="struct" title="c/language/struct">structs</a>, <a href="union" title="c/language/union">unions</a> and <a href="enum" title="c/language/enum">enumerated types</a>. Note that all three kinds of tags share one name space.</div> <div class="t-li1">
+<span class="t-li">3)</span> Member names: all identifiers declared as members of any one <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a>. Every struct and union introduces its own name space of this kind.</div> <table class="t-rev-begin"> <tr class="t-rev t-since-c23">
+<td> <span class="t-li">4)</span> Global attribute name space: <a href="attributes" title="c/language/attributes">attribute tokens</a> defined by the standard or implementation-defined attribute prefixes. <span class="t-li">5)</span> Non-standard attribute names: attribute names following attribute prefixes. Each attribute prefix has a separate name space for the implementation-defined attributes it introduces. </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td>
+</tr> </table> <div class="t-li1">
+<span class="t-li">6)</span> All other identifiers, called <i>ordinary identifiers</i> to distinguish from <span class="t-v">(1-5)</span> (function names, object names, typedef names, enumeration constants).</div> <p>At the point of lookup, the name space of an identifier is determined by the manner in which it is used:</p>
+<div class="t-li1">
+<span class="t-li">1)</span> identifier appearing as the operand of a <a href="goto" title="c/language/goto">goto statement</a> is looked up in the label name space.</div> <div class="t-li1">
+<span class="t-li">2)</span> identifier that follows the keyword <code>struct</code>, <code>union</code>, or <code>enum</code> is looked up in the tag name space.</div> <div class="t-li1">
+<span class="t-li">3)</span> identifier that follows the <a href="operator_member_access" title="c/language/operator member access">member access</a> or member access through pointer operator is looked up in the name space of members of the type determined by the left-hand operand of the member access operator.</div> <table class="t-rev-begin"> <tr class="t-rev t-since-c23">
+<td> <span class="t-li">4)</span> identifier that directly appears in an attribute specifier (<code>[[...]]</code>) is looked up in the global attribute name space. <span class="t-li">5)</span> identifier that follows the <code>::</code> token following an attribute prefix is looked in the name space introduced by the attribute prefix. </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td>
+</tr> </table> <div class="t-li1">
+<span class="t-li">6)</span> all other identifiers are looked up in the name space of ordinary identifiers.</div> <h3 id="Notes"> Notes</h3> <p>The names of <a href="../preprocessor/replace" title="c/preprocessor/replace">macros</a> are not part of any name space because they are replaced by the preprocessor prior to semantic analysis.</p>
+<p>It is common practice to inject struct/union/enum names into the name space of the ordinary identifiers using a <a href="typedef" title="c/language/typedef">typedef</a> declaration:</p>
+<div class="c source-c"><pre data-language="c">struct A { }; // introduces the name A in tag name space
+typedef struct A A; // first, lookup for A after "struct" finds one in tag name space
+ // then introduces the name A in the ordinary name space
+struct A* p; // OK, this A is looked up in the tag name space
+A* q; // OK, this A is looked up in the ordinary name space</pre></div> <p>A well-known example of the same identifier being used across two name spaces is the identifier <code>stat</code> from the POSIX header <code>sys/stat.h</code>. It <a rel="nofollow" class="external text" href="http://pubs.opengroup.org/onlinepubs/9699919799/">names a function</a> when used as an ordinary identifier and <a rel="nofollow" class="external text" href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html">indicates a struct</a> when used as a tag.</p>
+<p>Unlike in C++, enumeration constants are not struct members, and their name space is the name space of ordinary identifiers, and since there is no struct scope in C, their scope is the scope in which the struct declaration appears:</p>
+<div class="c source-c"><pre data-language="c">struct tagged_union {
+ enum {INT, FLOAT, STRING} type;
+ union {
+ int integer;
+ float floating_point;
+ char *string;
+ };
+} tu;
+
+tu.type = INT; // OK in C, error in C++</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-since-c23">
+<td> <p>If a standard attribute, an attribute prefix, or a non-standard attribute name is not supported, the invalid attribute itself is ignored without causing an error.</p>
+</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td>
+</tr> </table> <h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">void foo (void) { return; } // ordinary name space, file scope
+struct foo { // tag name space, file scope
+ int foo; // member name space for this struct foo, file scope
+ enum bar { // tag name space, file scope
+ RED // ordinary name space, file scope
+ } bar; // member name space for this struct foo, file scope
+ struct foo* p; // OK: uses tag/file scope name "foo"
+};
+enum bar x; // OK: uses tag/file-scope bar
+// int foo; // Error: ordinary name space foo already in scope
+//union foo { int a, b; }; // Error: tag name space foo in scope
+
+int main(void)
+{
+ goto foo; // OK uses "foo" from label name space/function scope
+
+ struct foo { // tag name space, block scope (hides file scope)
+ enum bar x; // OK, uses "bar" from tag name space/file scope
+ };
+ typedef struct foo foo; // OK: uses foo from tag name space/block scope
+ // defines block-scope ordinary foo (hides file scope)
+ (foo){.x=RED}; // uses ordinary/block-scope foo and ordinary/file-scope RED
+
+foo:; // label name space, function scope
+}</pre></div> </div> <h3 id="References"> References</h3> <ul>
+<li> C17 standard (ISO/IEC 9899:2018): </li>
+<ul><li> 6.2.3 Name spaces of identifiers (p: 29-30) </li></ul>
+<li> C11 standard (ISO/IEC 9899:2011): </li>
+<ul><li> 6.2.3 Name spaces of identifiers (p: 37) </li></ul>
+<li> C99 standard (ISO/IEC 9899:1999): </li>
+<ul><li> 6.2.3 Name spaces of identifiers (p: 31) </li></ul>
+<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
+<ul><li> 3.1.2.3 Name spaces of identifiers </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/lookup" title="cpp/language/lookup">C++ documentation</a></span> for <span class=""><span>Name lookup</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/name_space" class="_attribution-link">https://en.cppreference.com/w/c/language/name_space</a>
+ </p>
+</div>