【问题标题】:C++ truncating when casting to smaller types转换为更小的类型时 C++ 截断
【发布时间】:2016-08-06 11:14:19
【问题描述】:

我有一个 64 位长整数,其中包含一些位域。我需要一个存储在第二个和第三个字节中的 16 位有符号整数,并将其添加到 32 位值。我正在使用这样的东西:

u32 Function( s32 value , u64 bitfield )
{
    return value + (s16) (bitfield >> 8)
}

我可以依靠编译器将位域转换为 16 位有符号整数,然后再将其扩展为 32 位有符号整数并执行加法吗?如果没有,我还应该如何截断剩余的字节并执行我需要的类型转换?

【问题讨论】:

    标签: c++ casting type-conversion bit-fields


    【解决方案1】:

    是的,但需要注意的是您依赖于编译器和体系结构特定的行为。当然,依赖这种行为会导致您陷入非常难以诊断的“功能”(错误)。

    你可能最好写出(告诉编译器)你想要什么,让优化通过和其他通过消除不必要的代码:

    u32 Function(s32 value, u64 bitfield)
    {
      // Extract 16 bit qty from 64-bit: (x|x|x|x|x|1|2|x), preserving
      // signedness
      return value + (s32) (((bitfield << 40) >> 48) & 0xffffffff);
    }
    

    (是的,在那里发表评论也会对未来的维护者有所帮助。)

    【讨论】:

    • 虽然此解决方案会截断不需要的信息,但不会保留 16 位的符号。我考虑过使用类似的东西:返回值+((s32)位域>16);虽然我相信这会奏效,但我发现它非常丑陋。
    • 好的,你想保留签名是公平的。但是,尽管“丑陋”,但您的意图是清楚的(位提取)并保留了签名。让编译器完成选择适当指令的艰苦工作。不要过早优化。
    • 已更新以保留签名并将 bitfield 上的操作保持为 u64,直到绝对必要为止。
    猜你喜欢
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    • 2012-11-10
    • 2021-12-07
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多