[C++-sig] bases + wrapper bug?

Roman Yakovenko roman.yakovenko at gmail.com
Sat Aug 18 19:54:55 CEST 2007

On 8/17/07, Piotr Jaroszyński <p.jaroszynski at gmail.com> wrote:
> Hello,
> I might have hit a bug in Boost.Python, but you tell me, simple c++ code - [1]
> and even simpler Python code - [2]. Running bug.py segfaults for me without
> the line marked in bug.cc. I think it's because DerivedWrapper uses
> bases<Base>, but Base is exposed through BaseWrapper.
> [1] - http://dev.gentooexperimental.org/~peper/boost/bug.cc
> [2] - http://dev.gentooexperimental.org/~peper/boost/bug.py

I will try to explain, how I understand this, but of course I could be wrong.

bp::class_<BaseWrapper, boost::noncopyable>
        .def("f", bp::pure_virtual(&Base::f))

bp::class_<DerivedWrapper, bp::bases<Base>, boost::noncopyable>
        // Without this line the Python code segfaults
        //.def("f", bp::pure_virtual(&Base::f))
At run time, behind PyObject you have holds DerivedWrapper class instance.
During the first registration of "f", type of "this" pointer is
BaseWrapper. I could be wrong, but the library doesn't scan for
registered [pure] virtual functions and re-registers them again with
the right "this" pointer.  So in your case: you call "f" with "this"
pointer type "DerivedWrapper", than library does casting for you from
DerivedWrapper to BaseWrapper and than it calls "f". Obviously this
cannot work, becase BaseWrapper and DerivedWrapper are not base and
derived classes.

You can test my explanation by changing DerivedWrapper implementation:

struct DerivedWrapper : Derived, BaseWrapper, bp::wrapper<Derived>
    virtual int f() const
        if (bp::override f = get_override("f"))
            return 1;

I think that in this case you don't have to register "f" twice.

Roman Yakovenko
C++ Python language binding

More information about the Cplusplus-sig mailing list