LARGE_INTEGER 和 DUMMYSTRUCTNAME

问题描述 投票:0回答:2

当我遇到 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 呢?我想知道也许有一些原因,比如兼容性。

c++
2个回答
2
投票

这显然是为了避免联合中出现匿名结构而进行的调整。 Visual C++ 已支持此功能,但语言标准不允许这样做。 (有关没有 DUMMYSTRUCTNAME 的结构声明,请参阅

无法理解 LARGE_INTEGER 结构
。)添加名称是为了使联合符合标准 C++,可能需要某种自动化工具。

LARGE_INTEGER

的更高版本
完全摆脱了结构,只拥有
QuadPart


0
投票

神奇的事情发生在预处理器中。面对以

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 上几次点击之后):

什么是匿名结构,更重要的是,如何告诉 windows.h 停止使用它们?

© www.soinside.com 2019 - 2024. All rights reserved.