title: Destruction order of static objects in shared libraries
body: <p>I have a main program (<code>main.cpp</code>) and a shared library (<code>test.h</code> and <code>test.cpp</code>):</p>
  
  <p>test.h:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  struct A {
      A() { printf("A ctor\n"); }
      ~A() { printf("A dtor\n"); }
  };
  
  A&amp; getA();
  </code></pre>
  
  <p>test.cpp:</p>
  
  <pre><code>#include "test.h"
  
  A&amp; getA() {
      static A a;
      return a;
  }
  </code></pre>
  
  <p>main.cpp:</p>
  
  <pre><code>#include "test.h"
  
  struct B {
      B() { printf("B ctor\n"); }
      ~B() { printf("B dtor\n"); }
  };
  
  B&amp; getB() {
      static B b;
      return b;
  }
  
  int main() {
      B&amp; b = getB();
      A&amp; a = getA();
      return 0;
  }
  </code></pre>
  
  <p>This is how I compile these sources on Linux:</p>
  
  <pre><code>g++ -shared -fPIC test.cpp -o libtest.so
  g++ main.cpp -ltest
  </code></pre>
  
  <p>Output on Linux:</p>
  
  <pre><code>B ctor
  A ctor
  A dtor
  B dtor
  </code></pre>
  
  <p>When I run this example on Windows (after some adjustments like adding <code>dllexport</code>) I get with MSVS 2015/2017:</p>
  
  <pre><code>B ctor
  A ctor
  B dtor
  A dtor
  </code></pre>
  
  <p>To me the first output seems to be compliant with the standard. For example see:
  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf" rel="noreferrer">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf</a></p>
  
  <p>From paragraph 3.6.3.1:</p>
  
  <blockquote>
    <p>If the completion of the constructor or dynamic initialization of an object with static storage
    duration is sequenced before that of another, the completion of the destructor of the second is sequenced
    before the initiation of the destructor of the first.</p>
  </blockquote>
  
  <p>That is if <code>B</code> object is constructed first it should be destroyed last - that what we see on Linux. But the Windows output is different. Is it a MSVC bug or am I missing something?</p>