为什么我需要从 `long &` 到 `int &` 的 reinterpret_cast,两者都是 32 位 (Windows LLP64)?
Why do I need reinterpret_cast from `long &` to `int &` where both are 32-bit (Windows LLP64)?
我在跨平台环境中使用 Qt。而我们 运行 陷入以下问题: 在 Windows 上,int
和 long int
都是 32 位整数;在 64 位 MacOS 和 Linux 上,int
是 32 位,long int
是 64 位(参见 https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models)。
因此,跨平台库倾向于提供它们自己的固定位类型定义。在 Windows 上,Qt 将 quint32
定义为 unsigned int
并且不使用 unsigned long
整数。另一个库将其 Uint32
定义为 unsigned long
。所以,两者实际上都是 32 位无符号整数,但具有不同的原始数据类型。
现在,碰巧我们尝试使用为 quint32
定义的 QDataStream
序列化和 Uint32
数据,令我们惊讶(或没有)的是,Visual C++ 抱怨QDataStream
运算符没有为 unsigned long
定义,这是真的,因为 Qt 使用几乎等价的 unsigned int
代替。
好的,解决方法是提供
#ifdef Q_OS_WIN
inline QDataStream & operator >> (QDataStream & stream, Uint32 & value)
{ return stream >> reinterpret_cast<quint32 &>(value); }
inline QDataStream & operator << (QDataStream & stream, Uint32 value)
{ return stream << quint32(value); }
#endif // def Q_OS_WIN
我的问题是:为什么我需要reinterpret_cast
?我会觉得 static_cast
更舒服,因为据我所知,数据类型实际上是相同的。这里是龙?
int
和 long
是不同的数据类型,即使它们恰好在其他方面具有相同的属性。
您的 operator>>
由于严格的别名违规导致未定义的行为;编写代码的正确方法是:
inline QDataStream & operator >> (QDataStream & stream, Uint32 & value)
{
quint32_t v;
stream >> v;
value = v;
return stream;
}
(注意:我假设 QDataStream>> 与 C++11 istream>> 具有相同的 属性,因为它在读取失败时将值设置为 0
;如果不是,则您需要包含一个分支,以便在读取失败时不执行 value = v;
。
您可以将 static_cast
用于 operator<<
,因为它是一个值转换。事实上,您应该能够完全忽略 operator<<
。
您在问题中抱怨的问题是项目自行构建 typedef 而不是使用标准化类型的必然结果。不幸的是,在项目决定转向标准化类型之前,这只是您必须处理的事情。如果两者都使用 uint32_t
那么这个问题就不会存在了。
我在跨平台环境中使用 Qt。而我们 运行 陷入以下问题: 在 Windows 上,int
和 long int
都是 32 位整数;在 64 位 MacOS 和 Linux 上,int
是 32 位,long int
是 64 位(参见 https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models)。
因此,跨平台库倾向于提供它们自己的固定位类型定义。在 Windows 上,Qt 将 quint32
定义为 unsigned int
并且不使用 unsigned long
整数。另一个库将其 Uint32
定义为 unsigned long
。所以,两者实际上都是 32 位无符号整数,但具有不同的原始数据类型。
现在,碰巧我们尝试使用为 quint32
定义的 QDataStream
序列化和 Uint32
数据,令我们惊讶(或没有)的是,Visual C++ 抱怨QDataStream
运算符没有为 unsigned long
定义,这是真的,因为 Qt 使用几乎等价的 unsigned int
代替。
好的,解决方法是提供
#ifdef Q_OS_WIN
inline QDataStream & operator >> (QDataStream & stream, Uint32 & value)
{ return stream >> reinterpret_cast<quint32 &>(value); }
inline QDataStream & operator << (QDataStream & stream, Uint32 value)
{ return stream << quint32(value); }
#endif // def Q_OS_WIN
我的问题是:为什么我需要reinterpret_cast
?我会觉得 static_cast
更舒服,因为据我所知,数据类型实际上是相同的。这里是龙?
int
和 long
是不同的数据类型,即使它们恰好在其他方面具有相同的属性。
您的 operator>>
由于严格的别名违规导致未定义的行为;编写代码的正确方法是:
inline QDataStream & operator >> (QDataStream & stream, Uint32 & value)
{
quint32_t v;
stream >> v;
value = v;
return stream;
}
(注意:我假设 QDataStream>> 与 C++11 istream>> 具有相同的 属性,因为它在读取失败时将值设置为 0
;如果不是,则您需要包含一个分支,以便在读取失败时不执行 value = v;
。
您可以将 static_cast
用于 operator<<
,因为它是一个值转换。事实上,您应该能够完全忽略 operator<<
。
您在问题中抱怨的问题是项目自行构建 typedef 而不是使用标准化类型的必然结果。不幸的是,在项目决定转向标准化类型之前,这只是您必须处理的事情。如果两者都使用 uint32_t
那么这个问题就不会存在了。