在winbase.h
标题中,您可以找到以下行:
#define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 )
STATUS_WAIT_0
在winnt.h
标题中定义如下:
#define STATUS_WAIT_0 ((DWORD)0x00000000L)
并且DWORD
是 typedef 的unsigned long
。
我的问题是,为什么要0
增加STATUS_WAIT_0
价值?
有两个可能的原因。首先是可读性。如果有一系列#define
s:
#define WAIT_OBJECT_0 ((STATUS_WAIT_0) + 0)
#define WAIT_OBJECT_1 ((STATUS_WAIT_0) + 1)
// ...
在这种情况下,出于正交性的原因进行指定是有意义((STATUS_WAIT_0) + 0)
的:您正在定义一系列基于 的值STATUS_WAIT_0
,而这个值恰好与 偏移0
,而不是其他某个值是偶然的。
第二个可能的原因涉及整体提升。作者想要WAIT_OBJECT_0
提升类型 of
STATUS_WAIT_0
,而不管STATUS_WAIT_0
. 添加确保整体提升。
其他答案尚未解决的一个重要问题是(NTSTATUS Values) STATUS_WAIT_0
的可能值之一。主要在编写设备驱动程序时使用。NTSTATUS
NTSTATUS
当您WaitFor...
对某事物执行 a 时,执行可能会下降到内核中,并且取决于您等待的设备驱动程序的结果将是一个NTSTATUS
类型 (1)
因此,用户模式下的等待结果基于内核模式下的等待结果是有道理的,因此:
#define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 )
现在,至于为什么我们添加零……正如 James Kanze 所说,它使事情在定义的情况下更具可读性WAIT_OBJECT_1
。一致性是可维护性的重要组成部分。
至于为什么STATUS_WAIT_0
要转换为DWORD
... 这是因为0x0L
作为常量的值会因编译器而异,因此转换可确保您确切知道类型有多大。
(1) 不是设备驱动程序的作者,我不能假设这句话 100% 正确,但它是有道理的 :)
正如您已经提到的,就编译器而言,WAIT_OBJECT_0
,STATUS_WAIT_0
和0
.
但是,与维护程序员沟通的内容有所不同。该行:
#define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 )
说这WAIT_OBJECT_0
与 相同STATUS_WAIT_0
,但不一定如此。该行表示由 表示的值WAIT_OBJECT_0
可以更改而不会产生任何后果。但是,如果它被写成:
#define WAIT_OBJECT_0 STATUS_WAIT_0
这表明它们是等价的并且(可能)以某种方式连接在一起。
或者,它可能只是在编码标准中。
这只是定义宏的一种风格,它是一个系列,其中系列的成员依赖于基值。
#define NONE 0
#define UNITY (NONE + 1)
#define COUPLE (NONE + 2)
#define TRIPLE (NONE + 3)
后来,在维护期间,如果决定将基值设为 60,则更NONE
改为 60 将更改所有这些值,因为它们是在基宏顶部定义的。它的另一种方法是
#define NONE 0
#define UNO (NONE + 1)
#define DUO (UNO + 1)
#define TRIO (DUO + 1)
在此特定实例中,基值和第一个等待对象值设置为相同,因为开发人员希望使用相同的整数值来表示两者。