I believe the following behaviour changes in 1.63 judging by the ChangeLog, though unfortunately I can only test 1.60 vs 1.66 at the moment. Using Enterprise Linux 7 with gcc 7.2.
Consider this module: #include <boost/python.hpp> #include <iostream> #include <memory> namespace bp = boost::python; struct X { ~X () { std::cout << "Bye bye" << std::endl; } }; BOOST_PYTHON_MODULE (pymodule) { bp::class_<X, std::shared_ptr<X>> x_wrap ("X"); // Not needed in newer boost bp::register_ptr_to_python<std::shared_ptr<X>> (); auto x1 = std::make_shared<X> (); auto x2 = bp::extract<std::shared_ptr<X>> (bp::object (x1)) (); // On a newer boost: use counts are not the same std::cout << x1.get () << ": "<< x1.use_count () << std::endl; // 2 std::cout << x2.get () << ": "<< x2.use_count () << std::endl; // 1 :( } For the older Boost, the reference counts are both two, but they are 2 and 1 respectively in the newer Boost. Is this expected? I wonder if there's some cleverness involving x2 somehow pointing to a BP object that in turn points to x1. Curiously X appears to only be destructed once, so it doesn't look like UB. Where it bites me is cleanup time. If I add the following to the end of the module, I get a segfault: static std::vector<std::shared_ptr<X>> v {x2}; Backtrace as follows: #0 subtype_dealloc (self=0x7ffff7e24050) at Objects/typeobject.c:955 #1 0x00007fffef9dfb59 in xdecref<_object> (p=<optimized out>) at ./boost/python/refcount.hpp:38 #2 reset (this=0x6c1f30) at ./boost/python/handle.hpp:222 #3 boost::python::converter::shared_ptr_deleter::operator() (this=0x6c1f30) at libs/python/src/converter/builtin_converters.cpp:35 #4 0x00007ffff7ff563a in _M_release (this=0x6c1f20) at .../bits/shared_ptr_base.h:154 #5 ~__shared_count (this=<optimized out>, __in_chrg=<optimized out>) at .../bits/shared_ptr_base.h:684 #6 ~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at .../bits/shared_ptr_base.h:1123 #7 ~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at .../bits/shared_ptr.h:93 #8 _Destroy<std::shared_ptr<X> > (__pointer=<optimized out>) at .../bits/stl_construct.h:98 #9 __destroy<std::shared_ptr<X>*> (__last=<optimized out>, __first=0x678920) at .../bits/stl_construct.h:108 #10 _Destroy<std::shared_ptr<X>*> (__last=<optimized out>, __first=<optimized out>) at .../bits/stl_construct.h:137 #11 _Destroy<std::shared_ptr<X>*, std::shared_ptr<X> > (__last=0x678930, __first=<optimized out>) at .../bits/stl_construct.h:206 #12 std::vector<std::shared_ptr<X>, std::allocator<std::shared_ptr<X> > >::~vector (this=0x7ffff7ff7a60 <init_module_pymodule()::v>, __in_chrg=<optimized out>) at .../bits/stl_vector.h:434 #13 0x00007ffff6d24e69 in __run_exit_handlers () from /lib64/libc.so.6 #14 0x00007ffff6d24eb5 in exit () from /lib64/libc.so.6 #15 0x00007ffff6d0db1c in __libc_start_main () from /lib64/libc.so.6 #16 0x00000000004007a1 in _start () Is this a new behaviour change, or a bug, or was it always dangerous and I have just been lucky until now? Many thanks, Charlie _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig