2009/6/25 J. Michael Owen <mikeo...@llnl.gov> > I can see what you're worried about here, but as a practical matter it is > very useful to be able to pass stuff by reference, and copying it under the > hood will break code. For instance, if the virtual functions modify the > state of the parameters passed by reference it will just not function > correctly when a copy is made. Or in the example I sent when copy > constructors are not available it won't even compile! > > In Boost.Python this can be handled by wrapping the intermediate arguments > with the boost::ref() function, which tells Boost.Python to pass the thing > along as reference rather than making a copy and on my own head be it if I > do something nefarious with that reference. I guess what I would like in > this case is the equivalent of an "on my own head be it" option. This is > kind of how I think of the pointer passing policy, like with the > "caller_owns_return" option. Wouldn't it be reasonable to allow us to > specify optionally that references should not be copied, but rather passed > along natively? With the default policy still being the more memory safe > option of doing the copy?
I can't really fault your logic. I just thought of something that makes some sense. If the wrapper did something like: _wrap_my_virtual_method (A &a) { PyA *py_A; py_A = PyObject_New(PyA, &PyA_Type); py_A->obj = &a; // --- code to call into Python (without consuming a reference to py_A) --- py_A->obj = NULL; Py_DECREF(py_A); } At the end of the virtual method call, if the called python code decided to keep a reference to py_A, it will have a py_A with NULL C++ object and so any method call on it will crash. And this would not need any options. It's always best to do the smart thing when possible without asking too many questions ;-) > > On Jun 24, 2009, at 3:31 PM, Gustavo Carneiro wrote: > > Sorry, but in this case the answer is no. The virtual method wrapper here >> receives a parameter from C++ and has to create a Python wrapper for it. >> The wrapper needs to own the object. The reason is that the Python method >> that is called may decide to keep a reference to the object. If the Python >> wrapper kept a "shared" reference to the same C++ object then it could at >> some point in time be keeping a reference to an object when the caller has >> already deallocated it. >> >> To summarize, the object copy is done because the alternative would be >> memory unsafe. >> >> This is one case where a C++ API blindly designed without considering >> language bindings may make it difficult to bind later on. Ideally, in this >> case you should pass a pointer to A, and even better A would have reference >> counting so that both caller and callee could own a reference to the same >> object at the same time... >> > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig@python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Gustavo J. A. M. Carneiro INESC Porto, Telecommunications and Multimedia Unit "The universe is always one step beyond logic." -- Frank Herbert
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig