title: Template subclass of non-template base from shared library causing Undefined symbols typeinfo for 'class' link error
body: <h1>Summary</h1>
  
  <p>I've built a shared library containing a non-template class from which I've derived a template class within the project that is linked to the library.</p>
  
  <p>When I compile/link the referencing project, I receive the following link error:</p>
  
  <pre><code>Undefined symbols for architecture x86_64:
    "typeinfo for BaseClass", referenced from:
        typeinfo for DerivedClass&lt;int&gt; in main.o
  </code></pre>
  
  <p>What does <code>typeinfo</code> actually refer to?  I am having trouble finding information about it, in order to dig deeper.</p>
  
  <p>The error almost seems to imply that BaseClass is being expected to have type information of some kind, but I don't understand what is missing.</p>
  
  <p>Also, I know this error often accompanies a <code>vtable for ...</code> link error, usually when you forget to provide a definition for a virtual method or define it as pure virtual, but I believe I've ruled that out with #1 in <strong>Things I've Tried</strong> below, since <code>main.cpp</code> would not have compile if <code>foo()</code>'s definition was not available from the library.</p>
  
  <h1>Source</h1>
  
  <p>I've distilled the classes to the following which still reproduce the problem:</p>
  
  <p><strong>BaseClass.h</strong> (part of shared library I'm linking against)</p>
  
  <pre><code>#ifndef BASECLASS_H_
  #define BASECLASS_H_
  
  class BaseClass
  {
      protected:
          int myField;
  
      public:
          BaseClass();
          virtual ~BaseClass() {}
  
          virtual void foo();
  };
  
  #endif
  </code></pre>
  
  <p><strong>BaseClass.cpp</strong> (compiled into the resulting dylib)</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include "BaseClass.h"
  
  __attribute__((visibility("default")))
  BaseClass::BaseClass()
      : myField(0)
  {
  
  }
  
  __attribute__((visibility("default")))
  void BaseClass::foo()
  {
      std::cout&lt;&lt;myField&lt;&lt;std::endl;
  }
  </code></pre>
  
  <p><strong>DerivedClass.h</strong> (in separate project that is linked against the library)</p>
  
  <pre><code>#ifndef DERIVEDCLASS_H_
  #define DERIVEDCLASS_H_
  
  #include &lt;BaseClass.h&gt;
  
  template &lt;typename T&gt;
  class DerivedClass : public BaseClass
  {
      protected:
          T data;
  
      public:
          DerivedClass(T data) : data(data) {}
          virtual ~DerivedClass() {}
  };
  
  #endif
  </code></pre>
  
  <p><strong>main.cpp</strong> (References DerivedClass that's expressing problem)</p>
  
  <pre><code>#include "DerivedClass.h"
  
  int main()
  {
  
      DerivedClass&lt;int&gt; derived(0);
      derived.foo();
  
      return 0;
  }
  </code></pre>
  
  <h2>Build commands</h2>
  
  <p><strong>Shared Library</strong></p>
  
  <p>Compilation:</p>
  
  <pre><code>g++ -O3 -Wall -c -fmessage-length=0 -fvisibility=hidden -MMD -MP -MF"src/BaseClass.d" -MT"src/BaseClass.o" -o "src/BaseClass.o" "../src/BaseClass.cpp"
  </code></pre>
  
  <p>Linking:</p>
  
  <pre><code>g++ -Xlinker -install_name -Xlinker "@rpath/libmylibrary.dylib" -dynamiclib -o "libmylibrary.dylib" ./src/BaseClass.o
  </code></pre>
  
  <p><strong>Referencing Project</strong></p>
  
  <p>Compilation:</p>
  
  <pre><code>g++ -I"/code/myproject/deps/mylibrary/include" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.cpp"
  </code></pre>
  
  <p>Linking:</p>
  
  <pre><code>g++ -L"/code/myproject/deps/mylibrary/bin" -Xlinker -rpath -Xlinker "@loader_path" -o "myproject"  ./src/InternalBaseClass.o ./src/main.o   -lmylibrary
  </code></pre>
  
  <h2>Environment Info</h2>
  
  <ul>
  <li><strong>OS:</strong> macOS 10.11.6 (El Capitan)</li>
  <li><strong>Compiler:</strong> Apple LLVM version 8.0.0 (clang-800.0.42.1) (g++ links to this)</li>
  <li><strong>Linker:</strong> ld</li>
  </ul>
  
  <h1>Things I've Tried</h1>
  
  <p>I've done these things to try to narrow down the cause to specifically being due to the subclass being a template, and the base class coming from a shared library.</p>
  
  <ol>
  <li><p><em>Ensuring BaseClass can be referenced on its own.</em>
   Tested this by changing <code>main.cpp</code> to include <code>BaseClass</code>, and instantiating it in <code>main()</code> and calling <code>foo()</code> on it.  Compiled &amp; linked without errors.</p></li>
  <li><p><em>Deriving from an internal base class instead of one from a shared library.</em>
   Tested this by creating a class called <code>InternalBaseClass</code> with exact same source, except for the <code>__attribute__</code> lines in the definition file, including it in the <code>DerivedClass</code> header in place of including <code>BaseClass</code>, and specifying it as the parent in the class declaration of <code>DerivedClass</code>. Compiled &amp; linked without errors.</p></li>
  <li><p><em>Making <code>DerivedClass</code> non-template.</em>
   Tested this by removing template declarations in <code>DerivedClass</code> and replacing references to the parameterized type <code>T</code> with <code>int</code>.  This compiles &amp; links without errors.</p></li>
  </ol>
  
  <p>Thanks in advance!</p>