Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is WAIT_OBJECT_0 defined as ((STATUS_WAIT_0 ) + 0 )

In the winbase.h header, you can find the following line:

#define WAIT_OBJECT_0       ((STATUS_WAIT_0 ) + 0 )

STATUS_WAIT_0 is defined in the winnt.h header as such:

#define STATUS_WAIT_0       ((DWORD)0x00000000L)

And DWORD is typedef'd to unsigned long.

My question is, why is 0 added to the STATUS_WAIT_0 value?

like image 743
zozermania Avatar asked Oct 18 '13 07:10

zozermania


2 Answers

There are two possible reasons. The first is readability. If there is a series of #defines:

#define WAIT_OBJECT_0 ((STATUS_WAIT_0) + 0)
#define WAIT_OBJECT_1 ((STATUS_WAIT_0) + 1)
//  ...

In this case, it makes sense to specify ((STATUS_WAIT_0) + 0) for reasons of orthogonality: you are defining a series of values based on STATUS_WAIT_0, and it is just by accident that this one happens to offset by 0, rather than some other value.

The second possible reason involves integral promotion. The author wanted WAIT_OBJECT_0 to have the promoted type of STATUS_WAIT_0, regardless of the type of STATUS_WAIT_0. The addition ensures integral promotion.

like image 81
James Kanze Avatar answered Sep 26 '22 21:09

James Kanze


One important point that the other answers haven't addressed is that STATUS_WAIT_0 is one of the possible values of NTSTATUS (NTSTATUS Values). NTSTATUS is used primarily when writing device drivers.

When you perform a WaitFor... on a thing, it's possible that execution will drop down into the kernel, and depending on what you're waiting for the result from the device driver will be an NTSTATUS type (1)

For this reason it makes sense that the result of a Wait in user-mode is based on the result of a Wait in kernel mode, hence:

#define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 )

Now, as to why we add the zero... as James Kanze states, it makes things much more readable in the cases where WAIT_OBJECT_1 were defined. Consistency is an important part of maintainability.

As for why STATUS_WAIT_0 is cast to a DWORD... it's because the value of 0x0L as a constant will vary depending on compiler, so the cast ensures you know exactly how big the type is.


(1) not being a writer of device drivers, I can make no assumptions that this statement is true 100% of the time, but it makes sense :)

like image 23
icabod Avatar answered Sep 23 '22 21:09

icabod