1

I've took a look into atlbase.h to see how CComPtr<> is implemented, and stumbled upon Release() function in base class CComPtrBase<> which releases the underlaying object like this:

// Release the interface and set to NULL
void Release() throw()
{
    T* pTemp = p;
    if (pTemp)
    {
        p = NULL;
        pTemp->Release();
    }
}

My intelect is not good enough to see what's the point of this temporary pointer pTemp?

Why this code isn't just:

   void Release() throw()
   {
       if (p)
       {
           p->Release();

           // EDIT:
           p = NULL;
       }
   }

Now if you take a look at destructor, the destructor is defined just like my expectation from above sample, what is the difference?

metablaster
  • 1,958
  • 12
  • 26

1 Answers1

1

There's two possible explanations here:

  1. If p->Release() throws then it will not be set to NULL in the second variant, while it will in the first. Note that the enclosing function is declared throw() so it shouldn't be throwing exceptions. It's possible that this function was written before the throw() specifier was added. (Or maybe the coder is used to coding defensively in these kinds of situations and used a common pattern.)
  2. The first variant can be tail-call optimized while the second one cannot.
cdhowie
  • 158,093
  • 24
  • 286
  • 300