title: VariantClear releases VT_DISPATCH -vs- MSDN documentation
body: <p>VS2015 C++ / Windows7 SP1</p>
  
  <p>Considering the following code:</p>
  
  <pre><code>CComPtr&lt;IFontDisp&gt; m_pFont;
  ::OleCreateFontIndirect(&amp;fdesc,IID_IFontDisp,(void**)&amp;m_pFont);
  VARIANT var = m_pFont; // PSEUDO CODE
  </code></pre>
  
  <p>after this,</p>
  
  <pre><code>var.vt = 9; //VT_DISPATCH
  var.DISPATCH = "oleaut32.dll/IFontDisp"
  </code></pre>
  
  <p>So all looks fine.
  Now I call </p>
  
  <pre><code>::VariantClear(var);
  </code></pre>
  
  <p>And I debug into (ASM), I found this:</p>
  
  <pre><code>    74CB2EA6  nop  
      CFont::Release:
  --&gt; 74CB2EA7  sub         dword ptr [esp+4],4  
      74CB2EAC  jmp         CFont::Release (74CB2E79h)  
      74CB2EAE  nop  
      74CB2EAF  nop  
      74CB2EB0  nop  
  </code></pre>
  
  <p>Following the code:</p>
  
  <pre><code>CFont::Release:
  --&gt; 74CB2E79  mov         edi,edi  
  74CB2E7B  push        ebp  
  74CB2E7C  mov         ebp,esp  
  74CB2E7E  push        esi  
  74CB2E7F  mov         esi,dword ptr [ebp+8]  
  74CB2E82  push        edi  
  74CB2E83  lea         eax,[esi+0A8h]  
  74CB2E89  push        eax  
  74CB2E8A  call        dword ptr [__imp__InterlockedDecrement@4 (74C91298h)]  
  74CB2E90  mov         edi,eax  
  74CB2E92  test        edi,edi  
  74CB2E94  je          CFont::Release+261h (74CB30DAh)  
  74CB2E9A  mov         eax,edi  
  74CB2E9C  pop         edi  
  74CB2E9D  pop         esi  
  74CB2E9E  pop         ebp  
  74CB2E9F  ret         4  
  </code></pre>
  
  <p>So as I see, it releases the COM interface.
  But if I see <a href="https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-variantclear" rel="nofollow noreferrer">MSDN doc</a> about VariantClear: </p>
  
  <blockquote>
    <p>if the variant to be cleared is a COM object that is passed by
    reference, the vtfield of the pvargparameter is VT_DISPATCH | VT_BYREF
    or VT_UNKNOWN | VT_BYREF. In this case, VariantClear does not release
    the object. Because the variant being cleared is a pointer to a
    reference to an object, VariantClear has no way to determine if it is
    necessary to release the object. It is therefore the responsibility of
    the caller to release the object or not, as appropriate.</p>
  </blockquote>
  
  <p>According to this, it should not call release on the IFontDisp.</p>
  
  <p>Can anybody explain what is going on here?</p>
  
  <p>Thanks.</p>