title: pybind11: not downcasting to non-polymorphic base class
body: <p>I'm seeing some odd behavior from <code>pybind11</code> when a polymorphic class inherits from a non-polymorphic base class. Consider:</p>
  <pre><code>struct Base {
      Base() { id = (long int)this; }
      int get_id() const { return id; }
      int get_bthis() const { return (long int)this; }
      long int id;
  };
  struct Poly: public Base {
      virtual long int polymethod() { return get_id(); }
      long int get_pthis(){ return (long int)this;}
  };
  </code></pre>
  <p>With the <code>pybind</code> of</p>
  <pre><code>#include &lt;pybind11/pybind11.h&gt;
  namespace py = pybind11;
  
  PYBIND11_MODULE(example, m) {
      py::class_&lt;Base&gt;(m, &quot;Base&quot;)
          .def(&quot;get_id&quot;, &amp;Base::get_id)
          .def(&quot;get_bthis&quot;, &amp;Base::get_bthis);
      py::class_&lt;Poly, Base&gt;(m, &quot;Poly&quot;)
          .def(&quot;get_pthis&quot;, &amp;Poly::get_pthis)
          .def(&quot;polymethod&quot;, &amp;Poly::polymethod);
  
      m.def(&quot;make_base&quot;,[]() { return new Base();});
      m.def(&quot;make_poly&quot;,[]() { return new Poly();});
  }
  </code></pre>
  <p>It appears the Poly-&gt;Base pointer is not upcast in the trampoline because <code>example.make_poly().get_id()</code> returns garbage; the <code>this</code> pointer is not properly offset by the vtable:</p>
  <pre><code>&gt;&gt;&gt; import example
  &gt;&gt;&gt; base = example.make_base()
  &gt;&gt;&gt; base.get_id() # Ok
  7038096
  &gt;&gt;&gt; base.get_bthis() # Ok
  7038096
  &gt;&gt;&gt; poly = example.make_poly()
  &gt;&gt;&gt; poly.get_pthis() # Ok
  7046720
  &gt;&gt;&gt; virt.polymethod() # Ok
  7046728
  &gt;&gt;&gt; poly.get_bthis() # BUGGY, get_bthis() should be same as polymethod()
  7046720
  &gt;&gt;&gt; poly.get_id() # BUGGY, but can crash!
  -1116853264
  </code></pre>
  <p>The equivalent in native C++ properly considers the base class offset:</p>
  <pre><code>#include &lt;iostream&gt;
  int main(int argc, char** argv) {
  
      auto base = new Base();
      std::cout &lt;&lt; &quot;base-&gt;get_this():&quot; &lt;&lt; base-&gt;get_this() &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;base-&gt;get_id():&quot; &lt;&lt; base-&gt;get_id() &lt;&lt; std::endl;
  
      auto virt = new Poly();
      std::cout &lt;&lt; &quot;poly-&gt;get_bthis():&quot; &lt;&lt; poly-&gt;get_bthis() &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;poly-&gt;get_id():&quot; &lt;&lt; poly-&gt;get_id() &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;poly-&gt;get_pthis():&quot; &lt;&lt; poly-&gt;get_pthis() &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;poly-&gt;polymethod():&quot; &lt;&lt; poly-&gt;polymethod() &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>
  <p>prints</p>
  <pre><code>base-&gt;get_bthis():14856208
  base-&gt;get_id():14856208
  
  poly-&gt;get_bthis():14856248
  poly-&gt;get_id():14856248
  poly-&gt;get_pthis():14856240
  poly-&gt;polymethod():14856248
  </code></pre>
  <p>I'm most suspicious of <code>py::class_&lt;Poly, Base&gt;(m, &quot;Poly&quot;)</code>, but without it I cannot use <code>Poly::get_id</code>. Is this a pybind bug, or am I not declaring my class inheritance correctly? Making <code>Base</code> also polymorphic (say by adding <code>virtual ~Base()</code>) makes everything work.</p>
  <p>Or is this ultimately down to static dispatch vs dynamic dispatch; the latter which &quot;requires&quot; polymorphic base classes in C++?</p>
  <p>Edited: a previous version of this question referred to a &quot;virtual class&quot;  instead of the correct term of &quot;polymorphic class&quot;.</p>