This question already has an answer here:
- Handling CoCreateInstance return value 2 answers
Imagine a situation:
CComPtr<IGraphBuilder> pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
if (SUCCEEDED(hr))
{
CComPtr<IMediaControl> pControl;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
if(SUCCEEDED(hr))
{...}
}
I wonder, if pControl
could ever be nullptr inside last block {...}
. The question occurred, because I saw that code:
if(SUCCEEDED(hr) && pControl)
{...}
I consider that part && pControl
as a redundant one. Am I right?
QueryInterface()
is required to provide a valid (so non-null) interface pointer on success and a null pointer on failure. However you don't know whether some specific implementation follows that rule and the code you cite most likely tries to be defensive.That said, the following
also calls
QueryInterface()
under the hood to retrieve the pointer to the requested interface. If the code wants to be defensive it should check thatpGraph
is non-null on success too.The problem here is you don't know how bad it is when you get
S_OK
and a null pointer. SupposeQueryInterface()
works like this (really bad code follows, not for use anywhere):great, the defensive code will avoid dereferencing a null pointer retrieved here together with
S_OK
returned but reference count will be incorrect - noone will have a chance to call matchingRelease()
. So you instantiate such an object, then callQueryInterface()
which works as above, the refcount is now 2, then youRelease()
the object once and it leaks. How bad it happens to turn out depends on a lot of factors.Same with
CoCreateInstance()
- it calls the sameQueryInterface()
under the hood. Both may be broken and your mileage may vary both with and without checking the retrieved pointer against null.