[C++-sig] Problem: held type, std::auto_ptr, ReferenceErrors.

Prabhu Ramachandran prabhu at aero.iitm.ernet.in
Fri Aug 22 18:21:55 CEST 2003


[ I sent this on 20 Aug 2003 08:53:10 +0530 and it probably got eaten up
somewhere.  Apologies if this appears twice. ]

Hi,

I'm running into problems again.  This time its related to pointers,
std::auto_ptr and possibly call policies.  I'm using gcc (2.95.4).
The code is a little long winded since I'm experimenting with a couple
of problems in one shot.


// holder.hpp -----------------------------------------
#include <vector>
#include <iostream>

struct A {
    virtual ~A() {}
    virtual void f() = 0;
};

struct B: A{
    void f() {std::cout << "B::f\n";}
};

struct HBase {
    virtual ~HBase() {}
    virtual std::size_t size() const = 0;
    virtual A* get(const std::size_t n) = 0;
};

struct Holder : HBase {
    Holder() {}
    ~Holder() {for (std::size_t i=0; i<arr.size(); ++i) delete arr[i];}    
    std::size_t size() const {return arr.size();}
    void add(A* a) {arr.push_back(a);}
    A* get(const std::size_t n) {return arr[n];}    

private:
    std::vector<A*> arr;
};

void func(A* a) {a->f();}

void f(HBase* h)
{
    std::cout << h->size() << std::endl;
    for (std::size_t i=0; i<h->size(); ++i)
        h->get(i)->f();
}
--------------------------------------------------


I wrap this with Pyste using std::auto_ptr as the holder using a Pyste
file like so:

--------------------------------------------------
A = Class('A', 'holder.hpp')
B = Class('B', 'holder.hpp')

def held_type_func(name):
    return 'std::auto_ptr< %s >'%name

holder(A, held_type_func)
holder(B, held_type_func)

HBase = Class('HBase', 'holder.hpp')
set_policy(HBase.get, return_value_policy(reference_existing_object))

Holder = Class('Holder', 'holder.hpp')
set_policy(Holder.get, return_value_policy(reference_existing_object))
add_wrapper  = Wrapper('add_wrapper', """
void add_wrapper(Holder* c, std::auto_ptr< B> o)
{
    c->add(o.get());
    o.release();
}
""")
set_wrapper(Holder.add, add_wrapper)

module_code('''    implicitly_convertible<std::auto_ptr<B_Wrapper>, std::auto_ptr<B> > ();\n''')

func = Function('func', 'holder.hpp')
f = Function('f', 'holder.hpp')
--------------------------------------------------

I can attach the resulting cpp file if needed but using this Pyste
file I generate a holder.so module and test it like so:

--------------------------------------------------
from holder import *
b = B()
print "b.f():"
b.f()
print "func(b):"
func(b)
h = Holder()
h.add(b)
x = h.get(0)
print "x.f():"
x.f()
print "func(x):"
func(x)
print "f(h):"
f(h)
--------------------------------------------------

Problem 1: 
^^^^^^^^^^
First spot of trouble is here:

b.f():
B::f
func(b):
B::f
x.f():
B::f
func(x):
Traceback (most recent call last):
  File "test_holder.py", line 13, in ?
    func(x)
Boost.Python.ArgumentError: Python argument types in
    B.f(B)
did not match C++ signature:
    f(Q227_GLOBAL_.N.holder.cppO3zZAb9B_Wrapper {lvalue})
    f(1B {lvalue})

If I remove the HeldType and leave it as it is, everything works fine
upto and including the func(x) call.  I also tried by specifying a
boost::shared_ptr<T> as the held type.  I did not need to use the
add_wrapper in these two cases.  That also seems to work just fine.
So this looks to be a bug similar to the one earlier where x.f() used
to fail when the held type was std::auto_ptr<T>.  AFAIK, this does not
look to be a problem with Pyste.

Problem 2: 
^^^^^^^^^^

The second problem is with the f(h) call.  I get the following error
when I use either std::auto_ptr<T> or boost::shared_ptr<T> as the held
type or use no held type at all.

f(h):
1
Traceback (most recent call last):
  File "test_holder.py", line 15, in ?
    f(h)
ReferenceError: Attempt to return dangling pointer to object of type: 1A


I also tried to use a return_internal_reference<1>(); instead of the
return_value_policy(reference_existing_object)) and get the same
results.  I also changed the HBase* argument to a Holder* argument
with the same results.


I'd appreciate very much if someone can tell me what I am doing wrong
here or if this is a bug.


Thanks!
prabhu




More information about the Cplusplus-sig mailing list