为什么我需要reinterpret_cast从`long&`到`int&`这两个都是32位(Windows LLP64)?

时间:2017-11-16 22:24:31

标签: c++ windows qt casting qdatastream

我在跨平台环境中与Qt合作。我们遇到了以下问题:在Windows上,intlong int都是32位整数;在64位MacOS和Linux上,int为32位,long int为64位(请参阅https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models)。

因此,跨平台库倾向于提供自己的固定位typedef。在Windows上,Qt将quint32定义为unsigned int,并且不使用unsigned long整数。另一个库定义其Uint32但是unsigned long。因此,两者实际上都是32位无符号整数,但具有不同的原始数据类型。

现在,我们尝试使用为QDataStream定义quint32数据的Uint32序列化,令我们惊讶(或不),Visual C ++抱怨{ {1}}运算符未被QDataStream定义为真,因为Qt使用了几乎等效的unsigned long

好的,解决方法是提供

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更舒服。这是龙吗?

1 个答案:

答案 0 :(得分:2)

intlong是不同的数据类型,即使它们恰好具有相同的属性。

由于严格的别名违规,您的operator>>会导致未定义的行为;编写代码的正确方法是:

inline QDataStream & operator >> (QDataStream & stream, Uint32 & value)
{ 
     quint32_t v;
     stream >> v;
     value = v;
     return stream;
}

(注意:我假设QDataStream&gt;&gt;具有与C ++ 11 istream&gt;&gt;相同的属性,因为它在读取失败时将值设置为0;如果没有,那么你&# 39; ll需要包含一个分支,以便在读取失败时不执行value = v;

您可以static_cast使用operator<<,因为它是值转换。实际上,您应该能够完全省略operator<<

您在问题中感叹的问题是构成自己的typedef而不是使用标准化类型的项目的必然结果。不幸的是,在项目决定转向标准化类型之前,这只是你必须要处理的事情。如果两者都使用了uint32_t,那么这个问题就不存在了。