When return E_POINTER and when E_INVALIDARG?

sharptooth picture sharptooth · Sep 15, 2009 · Viewed 7.3k times · Source

COM interfaces methods can return various HRESULT values to signal invalid argument values passed. When do I return E_POINTER and when E_INVALIDARG?

As I understand if a method receives an index in an encapsulated collection and it is out of bounds that is E_INVALIDARG. If a method receives an Interface** pointer where it is meant to store a pointer to a newly created object that's E_POINTER.

HRESULT CImpl::GetItem( long index; Interface** result )
{
    if( result == 0 ) {
        return E_POINTER;
    }
    if( index < 0 || index >= internalArray.size() ) {
        return E_INVALIDARG;
    }
    *result = CreateWrapperObject( internalArray[index] );
    return S_OK;
}

But what if it receives a WCHAR* buffer with a file name as an "in" parameter and this WCHAR* is null? Is this E_POINTER or E_INVALIDARG?

Or a method receives a pointer to some struct and is expected to fill the struct through that pointer and this pointer is null - is this E_POINTER or E_INVALIDARG?

HRESULT CImpl::SaveToFile( WCHAR* fileName )
{
    if( fileName == 0 ) {
       return // what to return here?
    }
    //... do actual work here
}

HRESULT CImpl::GetAttributes( Attributes* to )
{
    if( to == 0 ) {
       return // what to return here?
    }
    attributes->IsCool = getIsCool();
    attributes->Color = RGB( 0, 255, 0 );
    return S_OK;
}

What are the rules for when to return E_POINTER and when E_INVALIDARG when checking pointer type parameters?

Answer

Shay Erlichmen picture Shay Erlichmen · Sep 15, 2009

You return E_POINTER when the reference to the pointer of an out parameter is null, this consider to be an error code that indicates a bug in the program or in the interop layer.

You return E_INVALIDARG when there is an application level on with the parameter for example out of range issue or parameter that collide with each other.

In Your case, in SaveToFile(...) you should return E_INVLIADARG since it is not valid to pass empty file name, and in GetAttributes(...) you should return E_POINTER (if it's an out param) because you cannot fill the value.

And yes, we all L-O-V-E com :)