在 MSVC 编译器下使用最大成员初始化联合

Initialize union using largest member under MSVC compiler

我试图在 C++ 库(准确地说是 C++03)中将 LARGE_INTEGER 初始化为 0。以前,初始化是:

static LARGE_INTEGER freq = { 0 };

在 MinGW 下它产生了一个警告:

missing initializer for member '_LARGE_INTEGER::::HighPart'

所以我按照Can a union be initialized in the declaration?把初始化改成如下:

static LARGE_INTEGER freq = { .QuadPart = 0 };

我现在正在 Visual Studio 2015 下测试,它产生了一个错误:

81  static LARGE_INTEGER freq = { .QuadPart = 0 };
82  if (freq.QuadPart == 0)
83  {
84      if (!QueryPerformanceFrequency(&freq))
85          throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed ..."));
86 }

hrtimer.cpp(81): error C2059: syntax error: '.'
hrtimer.cpp(81): error C2143: syntax error: missing ';' before '}'
hrtimer.cpp(82): error C2059: syntax error: 'if'
hrtimer.cpp(83): error C2143: syntax error: missing ';' before '{'
hrtimer.cpp(83): error C2447: '{': missing function header (old-style formal list?)
hrtimer.cpp(87): error C2059: syntax error: 'return'

如何在 MSVC 编译器下将联合初始化为其最大成员?


微软对LARGE_INTEGER的定义如下:

#if defined(MIDL_PASS)
typedef struct _LARGE_INTEGER {
#else // MIDL_PASS
typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    } DUMMYSTRUCTNAME;
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;
#endif //MIDL_PASS
    LONGLONG QuadPart;
} LARGE_INTEGER;

{ .QuadPart = 0 }; 在 C++ 中是非法的。指定的初始值设定项仅适用于 C。您 link 提出 个问题。

在 C++03 中 [dcl.init.aggr]/15:(你的联合是一个聚合):

When a union is initialized with a brace-enclosed initializer, the braces shall only contain an initializer for the first member of the union.

因此,除非该成员是第一个成员,否则无法初始化 "the largest member"。


MinGW 警告是假的。 g++ 曾经为 = { 0 }; 发出警告,但这是一个常见的习惯用语,因此他们将其修复为不再这样做。我想你的版本有点旧。

在您的代码中,= { 0 }; 应将 DUMMYSTRUCTNAME 初始化为 {0, 0}。根据 this,联合的所有成员都是 64 位的,因此在这种特殊情况下,您实际上初始化了最大的成员。