storing/reading 不同大小的整数 to/from 联合时是否有任何转换?
Is there any conversions when storing/reading integers of different size to/from union?
阅读 Rapidjson 代码我发现了一些有趣的“类型双关”优化。
// By using proper binary layout, retrieval of different integer types do not need conversions.
union Number {
#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
struct I {
int i;
char padding[4];
}i;
struct U {
unsigned u;
char padding2[4];
}u;
#else
struct I {
char padding[4];
int i;
}i;
struct U {
char padding2[4];
unsigned u;
}u;
#endif
int64_t i64;
uint64_t u64;
double d;
}; // 8 bytes
看起来只有 BE CPU 受到此优化的影响。这如何提高性能?我想测试但是没有BE机器
维基百科says:
While not allowed by C++, such type punning code is allowed as "implementation-defined" by the C11 standard[15] and commonly used[16] in code interacting with hardware.[17]
那么它在 C++ 中合法吗?我相信在绝对大多数情况下它都能正常工作。但是我应该在新代码中使用它吗?
So is it legal in C++?
不,这在 C++ 中是不合法的(维基百科也已经声明 “虽然 C++ 不允许...”)。
在 c++ 中,union
只是为包含的 union
成员保留内存,这样就足以容纳最大的成员。该记忆由所有成员共享。
从用于初始化它的联合访问不同的成员,是未定义的行为。您需要事先决定与哪些 union
成员一起工作,如果这些成员被任何函数共享(这通常使用 类型鉴别器 完成)。
阅读 Rapidjson 代码我发现了一些有趣的“类型双关”优化。
// By using proper binary layout, retrieval of different integer types do not need conversions.
union Number {
#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
struct I {
int i;
char padding[4];
}i;
struct U {
unsigned u;
char padding2[4];
}u;
#else
struct I {
char padding[4];
int i;
}i;
struct U {
char padding2[4];
unsigned u;
}u;
#endif
int64_t i64;
uint64_t u64;
double d;
}; // 8 bytes
看起来只有 BE CPU 受到此优化的影响。这如何提高性能?我想测试但是没有BE机器
维基百科says:
While not allowed by C++, such type punning code is allowed as "implementation-defined" by the C11 standard[15] and commonly used[16] in code interacting with hardware.[17]
那么它在 C++ 中合法吗?我相信在绝对大多数情况下它都能正常工作。但是我应该在新代码中使用它吗?
So is it legal in C++?
不,这在 C++ 中是不合法的(维基百科也已经声明 “虽然 C++ 不允许...”)。
在 c++ 中,union
只是为包含的 union
成员保留内存,这样就足以容纳最大的成员。该记忆由所有成员共享。
从用于初始化它的联合访问不同的成员,是未定义的行为。您需要事先决定与哪些 union
成员一起工作,如果这些成员被任何函数共享(这通常使用 类型鉴别器 完成)。