title: C++ linker - Lack of duplicate symbols
body: <p>Why does the following code not give me a duplicate symbol linker error for Impl?</p>
  
  <p>I ran across this problem in some code I inherited and I'm recreating a shorter version here for simplicity.</p>
  
  <p>I have two classes, Foo and Bar, that each define a different version of the same struct (Impl) in each of their .cpp files.  So Foo.cpp and Bar.cpp each have an identically named Impl definition, but each one has a different inline constructor implementation.</p>
  
  <p>Both Foo and Bar have a member variable of type Impl and each forward declares Impl in its .h file.</p>
  
  <p>Foo.cpp news an instance of Bar inside its constructor.  What's interesting is what gets created depends on the order the files are linked.</p>
  
  <p>So this compilation command: </p>
  
  <pre><code>g++ -o a.out main.cpp Bar.cpp Foo.cpp
  </code></pre>
  
  <p>results in this output:</p>
  
  <pre><code>==&gt; main()
  Bar.cpp's Impl::Impl()
  Bar.cpp's Impl::Impl()
  &lt;== main()
  </code></pre>
  
  <p>And this command:</p>
  
  <pre><code>g++ -o a.out main.cpp Foo.cpp Bar.cpp
  </code></pre>
  
  <p>results in this output:</p>
  
  <pre><code>==&gt; main()
  Foo.cpp's Impl::Impl()
  Foo.cpp's Impl::Impl()
  &lt;== main()
  </code></pre>
  
  <p>I have tried this with gcc 4.1.2, Visual Studio 2008 and the Green Hills Multi 4.2.4 and they all produce the same result.</p>
  
  <hr>
  
  <h2>Foo.h</h2>
  
  <pre><code>#ifndef FOO_H
  
  struct Impl;
  class Bar;
  
  class Foo
  {
  public:
     Foo();
     ~Foo();
  
  private:
     Impl* p;
     Bar* bar;
  };
  
  #endif
  </code></pre>
  
  <h2>Foo.cpp</h2>
  
  <pre><code>#include &lt;iostream&gt;
  #include "Foo.h"
  #include "Bar.h"
  
  struct Impl
  {
     Impl()
     {
        std::cout &lt;&lt; "Foo.cpp's Impl::Impl()" &lt;&lt; std::endl;
     }
  };
  
  Foo::Foo()
   : p(new Impl),
     bar(new Bar)
  {
  }
  
  Foo::~Foo()
  {
     delete p;
     delete bar;
  }
  </code></pre>
  
  <h2>Bar.h</h2>
  
  <pre><code>#ifndef BAR_H
  #define BAR_H
  
  struct Impl;
  
  class Bar
  {
  public:
     Bar();
     ~Bar();
  
  private:
     Impl* p;
  };
  
  #endif
  </code></pre>
  
  <h2>Bar.cpp</h2>
  
  <pre><code>#include &lt;iostream&gt;
  #include "Bar.h"
  
  struct Impl
  {
     Impl()
     {
        std::cout &lt;&lt; "Bar.cpp's Impl::Impl()" &lt;&lt; std::endl;
     }
  };
  
  Bar::Bar()
   : p(new Impl)
  {
  }
  
  Bar::~Bar()
  {
     delete p;
  }
  </code></pre>
  
  <h2>main.cpp</h2>
  
  <pre><code>#include &lt;iostream&gt;
  #include "Foo.h"
  
  int main (int argc, char const *argv[])
  {
     std::cout &lt;&lt; "==&gt; main()" &lt;&lt; std::endl;
     Foo* f = new Foo();
     std::cout &lt;&lt; "&lt;== main()" &lt;&lt; std::endl;
     return 0;
  }
  </code></pre>