Differences between and best practices for
Why would a developer care?
These error types and their values are an often ignored part of the API contract. Using the return value incorrectly has the same type of consequences as using a cast to pass the wrong data type to a parameter of an API, code just doesn't work, and often fails first in the wild.
I recently began running into code like this:
// ERROR_SUCCESS is a WINERROR value
NTSTATUS status = ERROR_SUCCESS;
buffy = (WCHAR*)malloc(1);
if (buffy == NULL)
// this is an HRESULT value
status = E_OUTOFMEMORY;
// not only is this a WINERROR value, but HRESULT and
// NTSTATUS have many success values, not just one
if (status != ERROR_SUCCESS)
I went searching for information about what each type is and the relationships between them and how to use them correctly. Here is what I learned.
They are all 32bit values, some signed some unsigned. Some are defined in terms of bit fields and require macros or inline-functions to check their current state. Others are straight enumerations.
One of the complexities is best demonstrated with the
HRESULT type. Lets look at the out of memory condition. Here are some of the possible encodings:
There was some effort to make the values agree across the different expressions.
Many Api's will pick a set of return codes and then build internal maps from all the errors they receive from other Api's to the set they have decided to return. Thus most code calling Api's can expect that only one encoding will be returned.
Primary Windows Error TypesThere will be subsequent posts that expand on each of these types. Here is a summary:
|Structure||values in the range 0-16384|
|Success||value == ERROR_SUCCESS|
|Failure||value != ERROR_SUCCESS|
|Conversions||HRESULT is a superset
of all the other error types.
They all have lossless conversions
to HRESULT but it doesn't have
lossless conversions to anything else
Derived/Subset Windows Error Types
|Structure||A subset of the WINERROR values, redefined as RPC_S_...|
|Success||value == RPC_S_OK|
|Failure||value != RPC_S_OK|
|Type||SECURITY_STATUS or HRESULT|
|Structure||A subset of the HRESULT values (from FACILITY_NULL and FACILITY_SECURITY)|