operator & is called earlier than constructor

14 views
Skip to first unread message

smbat....@globallogic.com

unread,
Jan 26, 2016, 7:53:12 AM1/26/16
to cython-users
Hi All,

Few month ago you were fixing a bug with overridden operator& while deleting the object. Thank you very much for this, the fix works well. Unfortunately we hit similar issue again, this time when constructing the object.
Let me describe the problem once again. On the project I am working for we are using technology that is very close to Microsoft COM. There we use a smart pointer class for reference counting which is almost identical to well known CComPtr.

Unfortunately it brought us a big annoyance - overridden operator&

template <typename T>
class MyPtr
{
private:
    /// Current referenced interface
    T * _reference;

public:
 /// Allows passing this smart ptr as argument to methods which expect
 /// a T or a void, in order to fill it in. (e.g. QueryInterface). NOTE: if the internal
 /// reference is non-NULL it will be Released.
 /// to this object.
 /// \deprecated Please use the outArg() method (or inOutArg()) instead. 
    T** operator& ()
 {
 if (_reference)
 {
  _reference->Release()
  _reference = NULL;
 }
 return &_reference;
 }

... 

Well, it is deprecated but it still there. The issue is that operator&() returns not the object's address, but address of its internal member

We are using it in cython objects like this

cdef class MyClass:
 cdef MyPtr[IInterface] obj

Cython generates the following code for creation an object:

static PyObject* __pyx_tp_new_8MyModule_MyClass(PyTypeObject* t, PyObject* a, PyObject* k) {
  struct __pyx_obj_8MyModule_MyClass *p;
  new((void*)&(p->obj)) MyPtr < IInterface > ();
}

The issue is that operator & is called earlier than constructor. Luckily this works for most of the cases, someone (tp_new?) clears the memory, Smart Pointer’s internal reference gets NULL, so Release() is not called. One more lucky point is that pointer’s constructor does no work, so even when placement new() gets wrong address nothing breaks. 
Unfortunately when we tried to integrate new smart pointer version we got number of crashes. Internal structure of the pointer has changed and calling operator& before constructor now fails.
Is there any way to tweak tp_new function generation so that if calculates objects address in some other way without calling operator&()?
Reply all
Reply to author
Forward
0 new messages