Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about COM Release() method

Tags:

c++

com

I am learning about COM and reading about this code:

    STDMETHODIMP_ (ULONG) ComCar::Release()
{
   if(--m_refCount==0) delete this;
   return m_refCount;
}

My question is, if the m_refCount==0 and the object is deleted, how could the instance member variable m_refCount still exist and be returned? Please forgive me if my question is so naive cause I am a totally newbie on COM. Many thanks.

A related thread is here: How could a member method delete the object?

like image 413
smwikipedia Avatar asked Feb 22 '10 03:02

smwikipedia


2 Answers

Your concern is valid, the ref count should be moved into a local variable before the object is deleted.

STDMETHODIMP_ (ULONG) ComCar::Release()
{
   ULONG refCount = --m_refCount; // not thread safe
   if(refcount==0) delete this;
   return refCount;
}

But even that code is still wrong because it's not thread safe.

you should use code like this instead.

  STDMETHODIMP_ (ULONG) ComCar::Release()
  {
     LONG cRefs = InterlockedDecrement((LONG*)&m_refCount);
     if (0 == cRefs) delete this;
     return (ULONG)max(cRefs, 0);
  }
like image 122
John Knoeller Avatar answered Oct 23 '22 00:10

John Knoeller


Are you sure that the function is returning m_refCount?

I believe that accessing member variables or methods after an object has been deleted is undefined according to the standard, and you can never reliably do this.

The only way I think this could work is if the Release() method creates a local variable on the stack with a copy of the reference count, and this is returned via return value optimization.

like image 1
LeopardSkinPillBoxHat Avatar answered Oct 22 '22 22:10

LeopardSkinPillBoxHat