summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Fscope.html
blob: 654166dfbb59c4dc04ee661c8447292aa5359599 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    <h1 id="firstHeading" class="firstHeading">Scope</h1>            <p>Each <a href="identifier" title="c/language/identifier">identifier</a> that appears in a C program is <i>visible</i> (that is, may be used) only in some possibly discontiguous portion of the source code called its <i>scope</i>.</p>
<p>Within a scope, an identifier may designate more than one entity only if the entities are in different <a href="name_space" title="c/language/name space">name spaces</a>.</p>
<p>C has four kinds of scopes:</p>
<ul>
<li> block scope </li>
<li> file scope </li>
<li> function scope </li>
<li> function prototype scope </li>
</ul>  <h3 id="Nested_scopes"> Nested scopes</h3> <p>If two different entities named by the same identifier are in scope at the same time, and they belong to the same <a href="name_space" title="c/language/name space">name space</a>, the scopes are nested (no other form of scope overlap is allowed), and the declaration that appears in the inner scope hides the declaration that appears in the outer scope:</p>
<div class="c source-c"><pre data-language="c">// The name space here is ordinary identifiers.
 
int a;   // file scope of name a begins here
 
void f(void)
{
    int a = 1; // the block scope of the name a begins here; hides file-scope a
    {
      int a = 2;         // the scope of the inner a begins here, outer a is hidden
      printf("%d\n", a); // inner a is in scope, prints 2
    }                    // the block scope of the inner a ends here
    printf("%d\n", a);   // the outer a is in scope, prints 1
}                        // the scope of the outer a ends here
 
void g(int a);   // name a has function prototype scope; hides file-scope a</pre></div> <h3 id="Block_scope"> Block scope</h3> <p>The scope of any identifier declared inside a <a href="statements#Compound_statements" title="c/language/statements">compound statement</a>, including function bodies, <span class="t-rev-inl t-since-c99"><span>or in any expression, declaration, or statement appearing in <a href="if" title="c/language/if">if</a>, <a href="switch" title="c/language/switch">switch</a>, <a href="for" title="c/language/for">for</a>, <a href="while" title="c/language/while">while</a>, or <a href="do" title="c/language/do">do-while</a> statement</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>, or within the parameter list of a <a href="function_definition" title="c/language/function definition">function definition</a> begins at the point of declaration and ends at the end of the block or statement in which it was declared.</p>
<div class="c source-c"><pre data-language="c">void f(int n)  // scope of the function parameter 'n' begins
{         // the body of the function begins
   ++n;   // 'n' is in scope and refers to the function parameter
// int n = 2; // error: cannot redeclare identifier in the same scope
   for(int n = 0; n&lt;10; ++n) { // scope of loop-local 'n' begins
       printf("%d\n", n); // prints 0 1 2 3 4 5 6 7 8 9
   } // scope of the loop-local 'n' ends
     // the function parameter 'n' is back in scope
   printf("%d\n", n); // prints the value of the parameter
} // scope of function parameter 'n' ends
int a = n; // Error: name 'n' is not in scope</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-since-c99">
<td> <p>Until C99, selection and iteration statements did not establish their own block scopes (although if a compound statement was used in the statement, it had its usual block scope):</p>
<div class="c source-c"><pre data-language="c">enum {a, b};
int different(void)
{
    if (sizeof(enum {b, a}) != sizeof(int))
        return a; // a == 1
    return b; // b == 0 in C89, b == 1 in C99
}</pre></div> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td>
</tr> </table> <p>Block-scope variables have <a href="storage_duration" title="c/language/storage duration">no linkage</a> and <a href="storage_duration" title="c/language/storage duration">automatic storage duration</a> by default. Note that storage duration for non-VLA local variables begins when the block is entered, but until the declaration is seen, the variable is not in scope and cannot be accessed.</p>
<h3 id="File_scope"> File scope</h3> <p>The scope of any identifier declared outside of any block or parameter list begins at the point of declaration and ends at the end of the translation unit.</p>
<div class="c source-c"><pre data-language="c">int i; // scope of i begins
static int g(int a) { return a; } // scope of g begins (note, "a" has block scope)
int main(void)
{
    i = g(2); // i and g are in scope
}</pre></div> <p>File-scope identifiers have <a href="storage_duration" title="c/language/storage duration">external linkage</a> and <a href="storage_duration" title="c/language/storage duration">static storage duration</a> by default.</p>
<h3 id="Function_scope"> Function scope</h3> <p>A <a href="statements#Labels" title="c/language/statements">label (and only a label)</a> declared inside a function is in scope everywhere in that function, in all nested blocks, before and after its own declaration. Note: a label is declared implicitly, by using an otherwise unused identifier before the colon character before any statement.</p>
<div class="c source-c"><pre data-language="c">void f()
{
   {   
       goto label; // label in scope even though declared later
label:;
   }
   goto label; // label ignores block scope
}
 
void g()
{
    goto label; // error: label not in scope in g()
}</pre></div> <h3 id="Function_prototype_scope"> Function prototype scope</h3> <p>The scope of a name introduced in the parameter list of a <a href="function_declaration" title="c/language/function declaration">function declaration</a> that is not a definition ends at the end of the function <a href="declarations" title="c/language/declarations">declarator</a>.</p>
<div class="c source-c"><pre data-language="c">int f(int n,
      int a[n]); // n is in scope and refers to the first parameter</pre></div> <p>Note that if there are multiple or nested declarators in the declaration, the scope ends at the end of the nearest enclosing function declarator:</p>
<div class="c source-c"><pre data-language="c">void f ( // function name 'f' is at file scope
 long double f,            // the identifier 'f' is now in scope, file-scope 'f' is hidden
 char (**a)[10 * sizeof f] // 'f' refers to the first parameter, which is in scope
);
 
enum{ n = 3 };
int (*(*g)(int n))[n]; // the scope of the function parameter 'n'
                       // ends at the end of its function declarator
                       // in the array declarator, global n is in scope
// (this declares a pointer to function returning a pointer to an array of 3 int)</pre></div> <h3 id="Point_of_declaration"> Point of declaration</h3> <p>The scope of structure, union, and enumeration tags begins immediately after the appearance of the tag in a type specifier that declares the tag.</p>
<div class="c source-c"><pre data-language="c">struct Node {
   struct Node* next; // Node is in scope and refers to this struct
};</pre></div> <p>The scope of enumeration constant begins immediately after the appearance of its defining enumerator in an enumerator list.</p>
<div class="c source-c"><pre data-language="c">enum { x = 12 };
{
    enum { x = x + 1, // new x is not in scope until the comma, x is initialized to 13
           y = x + 1  // the new enumerator x is now in scope, y is initialized to 14
         };
}</pre></div> <p>The scope of any other identifier begins just after the end of its declarator and before the initializer, if any:</p>
<div class="c source-c"><pre data-language="c">int x = 2; // scope of the first 'x' begins
{
    int x[x]; // scope of the newly declared x begins after the declarator (x[x]).
              // Within the declarator, the outer 'x' is still in scope.
              // This declares a VLA array of 2 int.
}</pre></div> <div class="c source-c"><pre data-language="c">unsigned char x = 32; // scope of the outer 'x' begins
{
    unsigned char x = x;
            // scope of the inner 'x' begins before the initializer (= x)
            // this does not initialize the inner 'x' with the value 32, 
            // this initializes the inner 'x' with its own, indeterminate, value
}
 
unsigned long factorial(unsigned long n)
// declarator ends, 'factorial' is in scope from this point
{
   return n&lt;2 ? 1 : n*factorial(n-1); // recursive call
}</pre></div> <p>As a special case, the scope of a <a href="type" title="c/language/type">type name</a> that is not a declaration of an identifier is considered to begin just after the place within the type name where the identifier would appear were it not omitted.</p>
<h3 id="Notes"> Notes</h3> <p>Prior to C89, identifiers with external linkage had file scope even when introduced within a block, and because of that, a C89 compiler is not required to diagnose the use of an extern identifier that has gone out of scope (such use is undefined behavior).</p>
<p>Local variables within a loop body can hide variables declared in the init clause of a <a href="for" title="c/language/for">for</a> loop in C (their scope is nested), but cannot do that in C++.</p>
<p>Unlike C++, C has no struct scope: names declared within a struct/union/enum declaration are in the same scope as the struct declaration (except that data members are in their own <a href="name_space" title="c/language/name space">member name space</a>):</p>
<div class="c source-c"><pre data-language="c">struct foo {
    struct baz {};
    enum color {RED, BLUE};
};
struct baz b; // baz is in scope
enum color x = RED; // color and RED are in scope</pre></div> <h3 id="References"> References</h3>  <ul>
<li> C17 standard (ISO/IEC 9899:2018): </li>
<ul><li> 6.2.1 Scopes of identifiers (p: 28-29) </li></ul>
<li> C11 standard (ISO/IEC 9899:2011): </li>
<ul><li> 6.2.1 Scopes of identifiers (p: 35-36) </li></ul>
<li> C99 standard (ISO/IEC 9899:1999): </li>
<ul><li> 6.2.1 Scopes of identifiers (p: 29-30) </li></ul>
<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
<ul><li> 3.1.2.1 Scopes 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/scope" title="cpp/language/scope">C++ documentation</a></span> for <span class=""><span>Scope</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/scope" class="_attribution-link">https://en.cppreference.com/w/c/language/scope</a>
  </p>
</div>