title: Accessing static globals in an inline function
body: <p>I was having an odd problem that I narrowed down to the following test case:</p>
  
  <p>inl.h:</p>
  
  <pre><code>inline const char *fn() { return id; }
  </code></pre>
  
  <p>a.cc:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  static const char *id = "This is A";
  
  #include "inl.h"
  
  void A()
  {
      printf("In A we get: %s\n", fn());
  }
  </code></pre>
  
  <p>b.cc:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  static const char *id = "This is B";
  
  #include "inl.h"
  
  void B()
  {
      printf("In B we get: %s\n", fn());
  }
  
  extern void A();
  
  int main()
  {
      A();
      B();
      return 0;
  }
  </code></pre>
  
  <p>Now when I compile this with <code>g++ -O1 a.cc b.cc</code> it seems to work correctly.  I get:</p>
  
  <pre><code>In A we get: This is A
  In B we get: This is B
  </code></pre>
  
  <p>but if I compile with <code>g++ -O0 a.cc b.cc</code> I get:</p>
  
  <pre><code>In A we get: This is A
  In B we get: This is A
  </code></pre>
  
  <p>Note that I'm actually trying to use C11 semantics here, but I'm using g++ as gcc doesn't support C11 yet.</p>
  
  <p>Now as far as I can see, looking at both the C11 spec and the C++ spec (C++11 and older specs -- the semantics of inline and static globals does not seem to have changed), it should do what I want, and the failure when using <code>-O0</code> is a bug in gcc.</p>
  
  <p>Is this correct, or is there something somewhere in the spec that I'm missing that would make this undefined behavior?</p>
  
  <p><strong>Edit</strong></p>
  
  <p>The common answer seems to claim that <code>fn</code> needs to be declared as <code>static</code> for this to work.  But according to 6.7.4.6 of the C99 spec (6.7.4.7 in the C11 spec -- not sure about the C++ spec):</p>
  
  <blockquote>
    <p>If all of the file scope declarations for a function in a translation unit include the inline function
    specifier without extern, then the definition in that translation unit is an inline
    definition. An inline definition does not provide an external definition for the function,
    and does not forbid an external definition in another translation unit.</p>
  </blockquote>
  
  <p>So since there's no explicit <code>extern</code> here, these should be two independent inline functions with no interaction with each other.  No explicit <code>static</code> is required.</p>
  
  <p>Using an explicit static fixes the problem for C, but doesn't work for C++ inline member functions, as the <code>static</code> keyword has a completely different meaning in that case.</p>