[C++-sig] custom smart pointers

Roman Yakovenko roman.yakovenko at gmail.com
Wed Sep 13 21:10:31 CEST 2006


On 9/13/06, David Abrahams <dave at boost-consulting.com> wrote:
> FWIW, reference and const reference are totally separate cases.  const
> reference is essentially the same as pass-by-value; it only requires
> an rvalue conversion.  Mutable references require an lvalue conversion.
>
> > int ref_get_value( smart_ptr_t<base_i>& a ){
> >    return a->get_value();
> > }
> >
> > I am unable to call this function, I've got ArgumentError exception
>
> Naturally; there is no instance of smart_ptr_t<base_i> anywhere in the
> Python object for the reference to bind to.   The rules are the same
> as in C++:
>
>    int f(smart_ptr_t<base_i>& x) { return 0; }
>    smart_ptr_t<base_wrapper_t> y;
>    int z = f(y);                // fails to compile

Thank you for explanation.

> > int const_ref_get_value( const smart_ptr_t<base_i>& a ){
> >    return a->get_value();
> > }
> >
> > I am unable to call this function, I've got "segmentation fault" on Linux.
>
> Where does the segmentation fault occur?  Is 'a' a valid pointer
> within const_ref_get_value?
>
>
> Try building a minimal example that does nothing more than to
> reproduce your segmentation fault.  Then we'll see if the problem is
> in Boost.Python or in your code.

I built one and I don't like what I see. Let me explain.

smart_ptr_t{...};

struct derived_t{
    virtual int get_value(){ return 11;}
};


int val_get_value( smart_ptr_t<derived_t> a ){

    return a->get_value();

}



int const_ref_get_value( const smart_ptr_t<derived_t>& a ){

    if( a.get() )

        return a->get_value();


    else

        return -1;


}


namespace boost{ namespace python{
    get_pointer definition
    pointee definition
} }

Registration is pretty simple:

    bp::class_< derived_t, smart_ptr_t<derived_t> >( "derived_t" )

        .def( "get_value", &::derived_t::get_value );



    bp::def( "const_ref_get_value", &::const_ref_get_value );

    bp::def( "val_get_value", &::val_get_value );


Python test code also simple:

inst = cspc_ext.derived_t()
cspc_ext.val_get_value(inst)
cspc_ext.const_ref_get_value(inst) # <= in this line I get segmentation fault.

Now the mistery I saw:
1. If I remove "virtual" from derived_t::get_value everything works as expected.
2. If I comment "cspc_ext.val_get_value(inst)" expression, than
    cspc_ext.const_ref_get_value(inst)
    works.

I attached the source code.
I am using compiler g++ 4.0.3 on Ubuntu, CVS version of boost.

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cspc.cpp
Type: text/x-c++src
Size: 2792 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20060913/aa66d950/attachment.cpp>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.py
Type: text/x-python
Size: 592 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20060913/aa66d950/attachment.py>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Jamroot
Type: application/octet-stream
Size: 380 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20060913/aa66d950/attachment.obj>


More information about the Cplusplus-sig mailing list