title: Undefined reference to `vtable for XXX ( where XXX is a struct exception)
body: <p>i have the next code listing-6.1.cpp:</p>
  
  <pre><code>#include &lt;stack&gt;
  #include &lt;mutex&gt;
  #include &lt;memory&gt;
  #include &lt;future&gt;
  #include &lt;iostream&gt;
  #include &lt;exception&gt;
  using namespace std;
  
  struct empty_stack: std::exception
  {
  const char* what() const throw();
  };
  
  
  template&lt;typename T&gt;
  class threadsafe_stack
  {
  private:
      std::stack&lt;T&gt; data;
      mutable std::mutex m;
  public:
      threadsafe_stack(){}
      threadsafe_stack(const threadsafe_stack&amp; other)
      {
          std::lock_guard&lt;std::mutex&gt; lock(other.m);
          data=other.data;
      }
      threadsafe_stack&amp; operator=(const threadsafe_stack&amp;) = delete;
      void push(T new_value)
      {
          std::lock_guard&lt;std::mutex&gt; lock(m);
          data.push(std::move(new_value));
      }
      std::shared_ptr&lt;T&gt; pop()
      {
          std::lock_guard&lt;std::mutex&gt; lock(m);
          if(data.empty()) throw empty_stack();
          std::shared_ptr&lt;T&gt; const res(
              std::make_shared&lt;T&gt;(std::move(data.top())));
          data.pop();
          return res;
      }
      void pop(T&amp; value)
      {
          std::lock_guard&lt;std::mutex&gt; lock(m);
          if(data.empty()) throw empty_stack();
          value=std::move(data.top());
          data.pop();
      }
      bool empty() const
      {
          std::lock_guard&lt;std::mutex&gt; lock(m);
          return data.empty();
      }
  };
  
  
  struct Msg {
      size_t a;size_t b;size_t c;size_t d;
  };
  
  bool isCorrupted(const Msg&amp; m) {
      return !(m.a == m.b &amp;&amp; m.b == m.c &amp;&amp; m.c == m.d);
  }
  
  
  
  
  int main()
  {
      threadsafe_stack&lt;Msg&gt; stack;
  
      auto prod = std::async(std::launch::async, [&amp;]() {
          for (size_t i = 0; i &lt; 1000000; ++i){
              Msg m = { i, i, i, i };
              stack.push(m);
              //std::this_thread::sleep_for(std::chrono::microseconds(1));
              if (i % 1000 == 0) {
                  std::cout &lt;&lt; "stack.push called " &lt;&lt; i &lt;&lt; " times " &lt;&lt; std::endl;
              }
          }
      });
  
      auto cons = std::async(std::launch::async, [&amp;]() {
          for (size_t i = 0; i &lt; 1000000; ++i){
              try {
                  Msg m;
                  stack.pop(m);
                  if (isCorrupted(m)) {
                      std::cout &lt;&lt; i &lt;&lt;" ERROR: MESSAGE WAS CORRUPED:" &lt;&lt; m.a &lt;&lt; "-" &lt;&lt; m.b &lt;&lt; "-" &lt;&lt; m.c &lt;&lt; "-" &lt;&lt; m.d &lt;&lt; std::endl;
                  }
                  if (i % 1000 == 0) {
                      std::cout &lt;&lt; "stack.pop called " &lt;&lt; i &lt;&lt; " times " &lt;&lt; std::endl;
                  }
              }
              catch (empty_stack e) {
                  std::cout &lt;&lt; i &lt;&lt; " Stack was empty!" &lt;&lt; std::endl;
              }
          }
      });
  
      prod.wait();
      cons.wait();
  
      return 0;
  }
  </code></pre>
  
  <p>After it is compile with:</p>
  
  <pre><code>g++ -o exe.out listing-6.1.cpp -pthread -lboost_system -lboost_thread -std=c++0x
  </code></pre>
  
  <p>I have the next result:</p>
  
  <p>/tmp/ccqQnqlf.o: In function <code>empty_stack::empty_stack(empty_stack const&amp;)':
  listing-6.1.cpp:(.text._ZN11empty_stackC2ERKS_[_ZN11empty_stackC5ERKS_]+0x1d): undefined reference to</code>vtable for empty_stack'
  /tmp/ccqQnqlf.o:(.gcc_except_table+0x20): undefined reference to <code>typeinfo for empty_stack'
  /tmp/ccqQnqlf.o: In function</code>empty_stack::empty_stack()':
  listing-6.1.cpp:(.text._ZN11empty_stackC2Ev[_ZN11empty_stackC5Ev]+0x16): undefined reference to <code>vtable for empty_stack'
  /tmp/ccqQnqlf.o: In function</code>threadsafe_stack::pop(Msg&amp;)':
  listing-6.1.cpp:(.text._ZN16threadsafe_stackI3MsgE3popERS0_[_ZN16threadsafe_stackI3MsgE3popERS0_]+0x53): undefined reference to <code>typeinfo for empty_stack'
  /tmp/ccqQnqlf.o: In function</code>empty_stack::~empty_stack()':
  listing-6.1.cpp:(.text._ZN11empty_stackD2Ev[_ZN11empty_stackD5Ev]+0xb): undefined reference to `vtable for empty_stack'
  collect2: error: ld returned 1 exit status</p>