【发布时间】:2011-07-05 21:29:54
【问题描述】:
有人能问一下为什么定义了以下typedefs/#defines吗?与原版相比,它们有什么价值?
typedef char CHAR;
#define CONST const
typedef float FLOAT;
typedef unsigned __int64 DWORD64; //A 64-bit "double"-word?!
typedef ULONGLONG DWORDLONG; //What's the difference?
typedef ULONG_PTR DWORD_PTR; //What's the difference?
typedef long LONG_PTR; //Wasn't INT_PTR enough?
typedef signed int LONG32; //Why not "signed long"?
typedef unsigned int UINT; //Wait.. UINT is "int", "LONG" is also int?
typedef unsigned long ULONG; //ULONG is "long", but LONG32 is "int"? what?
typedef void *PVOID; //Why not just say void*?
typedef void *LPVOID; //What?!
typedef ULONG_PTR SIZE_T; //Why not just size_t?
而且,最重要的是:
#define VOID void //Assuming this is useful (?), why not typedef?
这些背后的原因是什么?是不是我不理解的某种抽象?
编辑:
对于那些提到编译器交叉兼容性的人:
我的问题不是关于他们为什么不使用unsigned long long 而不是DWORD64。我的问题是为什么有人会使用DWORD64 而不是ULONG64(反之亦然)? typedefed 不是都是 64 位宽吗?
或者,作为另一个例子:即使在一个旨在在各个方面欺骗我们的“假设”编译器中,ULONG_PTR 和 UINT_PTR 和 DWORD_PTR 之间有什么区别?这些所有抽象数据类型不都是同一个意思吗——SIZE_T?
但是,我am问他们为什么使用ULONGLONG 而不是long long——在含义上是否存在任何潜在差异,long long 和DWORDLONG 都没有涵盖?
【问题讨论】:
-
我怀疑其中有很多来自 win16 的黑暗时代,但我会把它留给那些真正在过去编写 windows 代码的人来回答:)
-
影响这些类型历史的因素有很多。一旦定义,就永远无法收回。 #define VOID void 已完成,因为最初 void* 最初不在 C 标准中(找不到链接...)。所以一些编译器没有识别它。但是如果你现在删除它,你就会破坏代码。当更新 SDK 时,没有人希望他的代码中断。更新的时候已经有太多问题了,为什么要在一些“世纪”未触及但现在突然不再编译的旧模块中打破它。
-
@Christopher:哦,关于
void的有趣案例。其他的呢,比如char?是否有任何时候char也未定义? -
DWORD64 与 UINT64 的冗余定义是由于微软的几个团队定义了自己的类型。也许内核团队喜欢 DWORD64,然后 GDI 团队来定义 UINT64。多年后,在整合 SDK 标头时,SDK 团队试图摆脱多个定义并将它们移至同一个基本标头。此团队无法删除定义。所以我们现在有这个“混乱”。 (这有点猜测..)