When implementing a COM
interface I always assign to the out parameters on success but should I do so also on error?
HRESULT CDemo::Div(/*[in]*/ LONG a, /*[in]*/LONG b, /*[out,retval]*/ LONG* pRet)
{
if (pRet == NULL)
return E_POINTER;
if (b == 0)
{
*pRet = 0; // is this redundant?
return E_INVALIDARG;
}
*pRet = a/b;
return S_OK;
}
At one time I was bit on the nose by not initializing an out parameter and assuming that if I initialized the variable it will remain that value if I don't change it inside the method. However I used this method from .NET
and since the marshaller sees that this is an [out]
parameter it discarded the initial value I placed on the call site and put in garbage after the function returned (it was fun debugging that, not).
Is assigning to an out
param even on failure overcompensation or should I really do it?
Edit: Even though formally one should not access out params if the function failed I often see (and sometimes write) code like this (using the example from sharptooth's post):
ISmth *pSmth = NULL;
pObj->GetSmth(&pSmth); // HRES is ignored
if (pSmth) // Assumes that if GetSmth failed then pSmth is still NULL
{
pSmth->Foo();
pSmth->Release();
}
This works fine in un-marshalled code (same thread apartment) but if a marshaller is involved is it smart enough to only set the return value if the function succeeded?