Shared vtables between classes of same name: call to virtual method crashes when casting to base type
<p>Check below for UPDATE, I could reproduce and need help.</p>

<p>I have a strange crash where some method works fine everywhere except in 1 place. Here's the code:</p>

<pre><code>struct base
{
    virtual wchar_t* get() = 0; // can be { return NULL; } doesn't matter
};

struct derived: public base
{
    virtual wchar_t* get() { return SomeData(); }
};

struct container 
{
    derived data;
};

// this is approx. how it is used in real program
void output(const base&amp; data) 
{ 
     data.get(); 
}

smart_ptr&lt;container&gt; item = GetItSomehow();
derived &amp;v1 = item-&gt;data;
v1.get(); // works OK
//base &amp;v2 = (base&amp;)derived; // the old line, to understand old comments in the question
base &amp;v2 = v1; // or base* v2 doesn't matter
v2.get(); // segmentation fault without going into method at all
</code></pre>

<p>Now, as I said, I call item->data.get() in many places on different objects and it works... always. Except for 1 place. But there it doesn't work <strong>only</strong> if casted to base class (<em>output</em> is an example why it is needed).</p>

<p>Now, the question is - <strong>HOW</strong> and <strong>WHY</strong> this can happen? I'd suspect pure virtual call but I don't call virtual method in the constructor. I don't see how the calls are different. I would suspect base method is abstract but it is same if I add a body to it.</p>

<p>I cannot provide a small example to test because, as I said, it works always, except for 1 place. If I knew why it doesn't work there, I wouldn't need the test sample because that would already be the answer...</p>

<p>P.S. The environment is Ubuntu 11.10 x64 but the program is compiled for 32 bit using gcc 4.5.2 custom build.</p>

<p>P.P.S. Another clue, not sure if related...</p>

<pre><code>warning: can't find linker symbol for virtual table for `derived::get' value
warning:   found `SomeOtherDerivedFromBaseClass::SomeOtherCrazyFunction' instead
</code></pre>

<p>in the real program</p>

<p>UPDATE: Any chance this can happen because of gcc linking vtable to a wrong class with same name but inside different shared library? The "derived" class in real app actually defined in several shared libraries, and worse, there's another similar class with same name but different interface. What's strange is that without casting to base class it works.</p>

<p>I am especially interested in gcc/linking/vtables details here.</p>

<p>Here's how I seem to reproduce:</p>

<pre><code>// --------- mod1.h
class base
{
public:
   virtual void test(int i); // add method to make vtables different with mod2
   virtual const char* data();
};

class test: public base
{
public:
   virtual const char* data();
};


// --------- mod2.h
class base
{
public:
   virtual const char* data();
};

class test: public base
{
public:
   virtual const char* data();
};

// --------- mod2.cpp
#include "mod2.h"
const char* base::data() { return "base2"; }
const char* test::data() { return "test2"; }

// --------- modtest.cpp
#include &lt;stdio.h&gt;
// !!!!!!!!! notice that we include mod1
#include "mod1.h"

int main()
{
   test t;
   base&amp; b = t;
   printf("%s\n", t.data());
   printf("%s\n", b.data());
   return 0;
}

// --------- how to compile and run
g++ -c mod2.cpp &amp;&amp; g++ mod2.o modtest.cpp  &amp;&amp; ./a.out

// --------- output from the program
queen3@pro-home:~$ ./a.out 
test2
Segmentation fault
</code></pre>

<p>In the modtest above, if we include "mod2.h" instead of "mod1.h", we get normal "test2\ntest2" output without segfault.</p>

<p>The question is - what is the exact mechanism for this? How to detect and prevent? I knew that static data in gcc will be linked to single memory entry, but vtables...</p>
