binder icon indicating copy to clipboard operation
binder copied to clipboard

`pointer to member conversion via virtual base` happening inside pybind11

Open adamnovak opened this issue 4 years ago • 1 comments

I'm having a problem with the cl.def() calls generated to bind methods that override methods inherited from a virtual base class:

/home/anovak/workspace/vg/deps/libbdsg/build/_deps/pybind11-src/include/pybind11/pybind11.h: In instantiation of ‘Return (Derived::* pybind11::method_adaptor(Return (Class::*)(Args ...) const))(Args ...) const [with Derived = bdsg::HandleGraphProxy<bdsg::BasePackedGraph<bdsg::STLBackend> >; Return = handlegraph::handle_t; Class = handlegraph::HandleGraph; Args = {const long long int&, bool}]’:
/home/anovak/workspace/vg/deps/libbdsg/build/_deps/pybind11-src/include/pybind11/pybind11.h:1118:45:   required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def(const char*, Func&&, const Extra& ...) [with Func = handlegraph::handle_t (handlegraph::HandleGraph::*)(const long long int&, bool) const; Extra = {char [182], pybind11::arg, pybind11::arg}; type_ = bdsg::HandleGraphProxy<bdsg::BasePackedGraph<bdsg::STLBackend> >; options = {std::shared_ptr<bdsg::HandleGraphProxy<bdsg::BasePackedGraph<bdsg::STLBackend> > >, bdsg::AbstractGraphProxy<bdsg::BasePackedGraph<bdsg::STLBackend> >, handlegraph::HandleGraph}]’
/home/anovak/workspace/vg/deps/libbdsg/bdsg/cmake_bindings/bdsg/graph_proxy.cpp:70:395:   required from here
/home/anovak/workspace/vg/deps/libbdsg/build/_deps/pybind11-src/include/pybind11/pybind11.h:1041:12: error: pointer to member conversion via virtual base ‘handlegraph::HandleGraph’

The code looks like this:

cl.def("get_handle", (struct handlegraph::handle_t (handlegraph::HandleGraph::*)(const long long &, bool) const) &handlegraph::HandleGraph::get_handle, "Look up the handle for the node with the given ID in the given orientation\n\nC++: handlegraph::HandleGraph::get_handle(const long long &, bool) const --> struct handlegraph::handle_t", pybind11::arg("node_id"), pybind11::arg("is_reverse"));

get_handle is inherited from a virtual handlegraph::HandleGraph base class of the class (bdsg::HandleGraphProxy<bdsg::BasePackedGraph<bdsg::STLBackend> >) I am trying to bind.

Somehow this induces an attempt to downcast a pointer to a member from one based on the derived class to one based on the virtual base class, which isn't allowed because the offset to the virtual base class from its immediate parent class may change, depending on if the parent class is inherited from in another class. I don't see such a cast happening right here; something in pybind11 must be being induced to do it.

I don't have this problem with other classes that inherit and define these methods via a non-virtual immediate base class, and I don't have this problem with other classes that inherit these methods from a virtual base class but don't immediately define them in the inheriting class.

I have binder 788ab422f9e919478944d79d5890441a964dd1db and pybind11 a54eab92d265337996b8e4b4149d9176c2d428a6.

adamnovak avatar Dec 09 '21 20:12 adamnovak

The latest pybind11 59aa99860c60bd171b9565e9920f125fdb749267 does not help.

adamnovak avatar Dec 09 '21 20:12 adamnovak

@adamnovak do you have a minimal example that replicates the issue?

kliegeois avatar Oct 21 '22 22:10 kliegeois

I didn't make one, but to fix it I had to remove the virtual base class in the hierarchy. So I think you should be able to see this with just:

struct A {
    virtual void method() = 0;
};

struct B : virtual public A {
    virtual void method() {
    }
};

Or maybe:

struct A {
    virtual void method() = 0;
};

struct B : virtual public A {
    
};

struct C : public B {
    virtual void method() {
    }
};

My full code that wasn't working should have been https://github.com/vgteam/libbdsg/pull/134/commits/b331d49c00ab3758e9aa8f7a0b6f65012ffa9052 and it would have been fixed by https://github.com/vgteam/libbdsg/pull/134/commits/b7aab61129945e32a114123e6f21d2207314413a which tried a different approach.

adamnovak avatar Oct 24 '22 16:10 adamnovak

Looks like https://github.com/RosettaCommons/binder/issues/241#issuecomment-1287932026 says the fact that some of these were templates in my code is important.

adamnovak avatar Oct 24 '22 16:10 adamnovak

Thanks @adamnovak for your comments!

kliegeois avatar Oct 26 '22 20:10 kliegeois

@adamnovak this should be fixed in 92d183a1ed0ff830b1ace245c49956751dca8d2f - but please feel free to re-open if you still experience the issue. Thanks,

lyskov avatar Oct 26 '22 21:10 lyskov