Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>this is useful when you need to access a variable that resides within another translation unit, without exposing the external variable globally (for a few reasons, like name collision, or that the the variable <em>shouldn't</em> be directly accessed, so <a href="http://en.wikipedia.org/wiki/Static_variable" rel="nofollow"><code>static</code></a> was used to limit its scope, but that TU's header still needs access).</p> <p>As an example, lets say we have a translation unit <code>foo.c</code>, it contains:</p> <pre><code>//foo.c static int i = 0; </code></pre> <p><code>i</code> shouldn't be changed or directly accessed outside <code>foo.c</code>, however, <code>foo.h</code> comes along requiring access to <code>i</code> for an inline function, but <code>i</code> shouldn't be exposed to any translation unit using <code>foo.h</code>, so we can use <code>extern</code> at functional level, to expose it only during the scope of <code>IncI</code>, the inline function requiring the use of <code>i</code>:</p> <pre><code>//foo.h inline void IncI(int val) { extern int i; i += val; } </code></pre> <hr> <p>Your second example is 'disallowed' because the compiler thinks you are trying to bind two different variables to the same symbol name, ie: it creates the <code>static i</code> at local scope, but searches for the <code>extern int i</code> at global scope, but doesn't find it, because <code>static i</code> as at the function scope. a more clever compiler would just fix the linkage to the <code>static i</code>, whether or not this follows standards I wouldn't know.</p> <hr> <p>Now that I have a <a href="http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf" rel="nofollow">C standards document</a> to work from (shame on me I know...), we can see what the official stance is (in C99):</p> <blockquote> <p>6.2.2 Linkages of identifiers</p> <p>Section 3:</p> <p>If the declaration of a file scope identifier for an object or a function contains the storageclass specifier static, the identifier has internal linkage.</p> <p>Section 4:</p> <p>For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.</p> </blockquote> <p>thus, because <code>static</code> will cause internal linkage, the <code>extern</code> will bring that linkage into the current scope. there is also a footnote stating that this may cause hiding of variables:</p> <blockquote> <p>23) As specified in 6.2.1, the later declaration might hide the prior declaration.</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload