当我遇到 LARGE_INTEGER 的定义时。我发现一些问题:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} DUMMYSTRUCTNAME;
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
我们可以重写如下:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} DUMMYSTRUCTNAME;
LONGLONG QuadPart;
} LARGE_INTEGER;
我认为结构体 u 是重复的。那么为什么 MSVC 会这样实现 LARGE_INTEGER 呢?我想知道也许有一些原因,比如兼容性。
这显然是为了避免联合中出现匿名结构而进行的调整。 Visual C++ 已支持此功能,但语言标准不允许这样做。 (有关没有 DUMMYSTRUCTNAME
的结构声明,请参阅
无法理解 LARGE_INTEGER 结构。)添加名称是为了使联合符合标准 C++,可能需要某种自动化工具。
的更高版本完全摆脱了结构,只拥有
QuadPart
。
神奇的事情发生在预处理器中。面对以
ALL_CAPS
开头的 DUMMY
标识符似乎已经暗示了这一点。如果我们想象以下 DUMMYSTRUCTNAME
, 的定义
#define DUMMYSTRUCTNAME
那么上面的结构定义就完全有意义了:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
}; // <--- now we have an anonymous struct
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
如果您想让初始化更加明确,
u
仍然很有用,如下面类似的 ULARGE_INTEGER 示例:
void print_FILETIME(FILETIME ft)
{
ULARGE_INTEGER uli = {.u={ft.dwLowDateTime, ft.dwHighDateTime}};
printf("FILETIME ft(HiLo): 0x%08lx_%08lx (%llu)\n",
ft.dwHighDateTime, ft.dwLowDateTime, uli.QuadPart);
}
今天我们可以成功地进行网络搜索
DUMMYSTRUCTNAME
并找到 Raymond Chen 撰写的这篇综合文章(在 Stack Overflow 上几次点击之后):