title: C++/Linux: Undefined reference to typeinfo, but virtual methods seem to be ok
body: <p>I have a base class for all exceptions in my project. It's implemented like this:</p>
  
  <p>Exception.hpp</p>
  
  <pre><code>class Exception : public std::exception
  {
  public:
  
      ELS_EXPORT_SYMBOL Exception(void) throw();
      ELS_EXPORT_SYMBOL explicit Exception(const std::string&amp; what) throw();
      ELS_EXPORT_SYMBOL Exception(const char* format, ...) throw()
              ELS_PRINTF_FUNC(2, 3);
      ELS_EXPORT_SYMBOL Exception(const Exception&amp; other) throw();
      ELS_EXPORT_SYMBOL Exception&amp; operator =(const Exception&amp; other)
              throw();
      ELS_EXPORT_SYMBOL virtual ~Exception(void) throw();
  
      ELS_EXPORT_SYMBOL virtual const char* what(void) const throw();
  
  protected:
  
      ELS_EXPORT_SYMBOL void _M_setWhat(const char* format, ::va_list va)
          throw();
  
  private:
  
      std::string _M_what;
  };
  
  #define ELS_EXC_VA_SET_WHAT(FORMAT)                                         \
      do                                                                      \
      {                                                                       \
          ::va_list va;                                                       \
          ::va_start(va, FORMAT);                                             \
          this-&gt;_M_setWhat(FORMAT, va);                                       \
          ::va_end(va);                                                       \
      }                                                                       \
      while (false)
  </code></pre>
  
  <p>Exception.cpp</p>
  
  <pre><code>Exception::Exception(void) throw()
      : std::exception(),
        _M_what("Exception")
  {
  
  }
  
  Exception::Exception(const std::string&amp; what) throw()
      : std::exception(),
        _M_what(what.empty() ? "Exception" : what)
  {
  
  }
  
  Exception::Exception(const char* format, ...) throw()
      : std::exception(),
        _M_what()
  {
      ELS_EXC_VA_SET_WHAT(format);
  }
  
  Exception::Exception(const Exception&amp; other) throw()
      : std::exception(other),
        _M_what(other._M_what)
  {
  
  }
  
  Exception&amp; Exception::operator =(const Exception&amp; other) throw()
  {
      std::exception::operator =(other);
      this-&gt;_M_what = other._M_what;
      return *this;
  }
  
  Exception::~Exception(void) throw()
  {
  
  }
  
  const char* Exception::what(void) const throw()
  {
      return this-&gt;_M_what.c_str();
  }
  
  void Exception::_M_setWhat(const char* format, ::va_list va) throw()
  {
      static const size_t BUFSIZE = 512;
  
      char buf[BUFSIZE];
  
      ::memset(buf, 0, BUFSIZE);
      ::vsnprintf(buf, BUFSIZE, format, va);
      this-&gt;_M_what = std::string(buf);
  }
  </code></pre>
  
  <p>These files are a part of a shared library compiled with the following options: </p>
  
  <pre><code>-Wall -fPIC -O2 -D_GNU_SOURCE -fvisibility=hidden -rdynamic -Wl,-E
  </code></pre>
  
  <p>The library itself compiles without any problem, but when I try and compile a binary and link it against it I get the following error:</p>
  
  <pre><code>Main.cpp:(.text+0x297): undefined reference to `typeinfo for els::except::Exception'
  </code></pre>
  
  <p>I googled a bit and the common answer is to either implement all virtual methods or make them pure. I don't see this problem here. What am I doing wrong?</p>