Udostępnij za pośrednictwem


Surprise! My success is your failure

Windows APIs often use HRESULTs. Almost every function returns an HRESULT and almost every caller is expected to check it. COM provides a few helpers for these tasks: SUCCEEDED()/FAILED() broadly check for success or for failure; HRESULT_FROM_WIN32() constructures a failure code from a Win32 error code; etc.

There is also a naming convension. Success codes are named FACILITY_S_REASON. Failures are FACILITY_E_REASON. But look out! There lurk amoung the multitude of errors, some that disguise success as failure!

Consider ICancelMethodCalls::TestCancel(). This function is supposed to return RPC_S_CALLPENDING or RPC_E_CALL_CANCELED. So a programmer might think they could simply call

BOOL fContinue = SUCCEEDED(p->TestCancel())

to see if the call is pending. 

I did this and discovered in testing that RPC_S_CALLPENDING is defined as a failure code: 0x80010115L. So fCountinue is always FALSE in the code above. It looks like RPC_S_WAITONTIMER is also this way. 

So much for naming convensions.