При реализации интерфейса COM
я всегда назначаю выходные параметры в случае успеха, но должен ли я делать это и в случае ошибки?
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;
}
Когда-то я был немного утомлен, не инициализируя выходной параметр и предполагая, что если я инициализирую переменную, она останется тем же значением, если я не изменю его внутри метода. Однако я использовал этот метод из .NET
, и поскольку маршаллер видит, что это параметр [out]
, он отбрасывает первоначальное значение, которое я поместил на сайт вызова, и помещает в мусор после возврата функции (это было забавно отлаживать, но не) ,
Является ли присвоение параметру out
даже при сверхкомпенсации отказа или мне действительно нужно это сделать?
Редактировать: Несмотря на то, что формально не следует обращаться к параметрам в случае сбоя функции, я часто вижу (и иногда пишу) код, подобный этому (используя пример из сообщения sharptooth ):
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();
}
Это прекрасно работает в коде без маршалинга (то же самое квартира потока ), но если маршаллер участвует, достаточно ли он умен, чтобы установить возвращаемое значение, только если функция выполнена успешно?