【问题标题】:Why do I need reinterpret_cast from `long &` to `int &` where both are 32-bit (Windows LLP64)?为什么我需要 reinterpret_cast 从 `long &` 到 `int &` 两者都是 32 位(Windows LLP64)?
【发布时间】:2018-04-30 14:37:30
【问题描述】:

我正在跨平台环境中使用 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)。

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

现在,我们尝试使用为quint32 定义的Uint32 数据和Uint32 数据的QDataStream 序列化,令我们惊讶(或没有),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 感觉更舒服,因为据我了解,数据类型实际上是相同的。这里有龙吗?

【问题讨论】:

    标签: c++ windows qt casting qdatastream


    【解决方案1】:

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

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

    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&lt;&lt;,因为它是一个值转换。事实上,您应该可以完全省略 operator&lt;&lt;

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

    【讨论】:

    • 实际上,那些是在uint32_t 出现之前开始处理这些问题的项目,我认为...关于跳过失败设置,您可以在分配之前添加if (QDataStream::Ok == stream.status())。感谢您的回答!
    • 有没有办法避免临时和分配?它看起来很没用......使用这里建议的联合 stackoverflow.com/questions/98650/…
    • 联合别名在标准 C++ 中是未定义的行为。 (在 C 中是允许的)。是否要依赖未定义的行为由您决定
    • 当然不是...我根据stream.status() 选择了您的解决方案以及条件赋值。
    猜你喜欢
    • 2022-08-11
    • 2013-08-01
    • 2011-11-08
    • 1970-01-01
    • 2011-03-05
    • 2010-12-12
    • 1970-01-01
    • 2011-11-04
    • 2012-07-09
    相关资源
    最近更新 更多