【问题标题】:Is bitmask necessary when assigning a value from a big type to a small one?将值从大类型分配给小类型时是否需要位掩码?
【发布时间】:2016-07-14 01:00:42
【问题描述】:

假设我想将 uint32_t 的低 16 位存储在 windows 上的 uint16_t 中,我也可以这样做

uint32_t value = 123456789;
uint16_t low1 = value; //like this
uint16_t low2 = value & 0xFFFF; //or this

结果似乎没有区别,但我找不到任何明确说明这是已定义行为的文档。在情况 X 或 Y 下会有所不同吗?还是这就是它的工作原理?

【问题讨论】:

标签: c++


【解决方案1】:

C++ 标准保证无符号类型的赋值和初始化为您提供模 2 的值n,其中 n 是无符号类型的值表示中的位。

在 Windows 中,所有位都参与值表示。

因此,使用位掩码除了在将来可能会更改类型时设置一个小绊脚石之外没有任何用处。


如果您绝对想使用面具,例如为了避免来自过度热心的编译器的编译警告,那么您可以像这样以与类型无关的方式执行此操作,假设类型是无符号的:

uint16_t low2 = value & uint16_t(-1);

这依赖于前面提到的 modulo-2n 保证。

【讨论】:

  • 使用~0作为掩码不是更好吗? -1 不是无符号整数的有效值,并且可能不会为所有系统(例如,没有两个补码的嵌入式系统)生成正确的位掩码。
  • @Rocki:代码有效,出于上述原因。与你的印象相反(你在地球上哪里得到的)它总是产生正确的面具,因为它是正确的类型。另一方面,~0 的类型不正确 int
  • @Alf 我的意思是uint16_t low2 = value & uint16_t(~0);。今天几乎所有的计算机都使用二进制补码,并且您假设 -1 产生正确的位掩码是正确的,但是想象一个具有二进制补码的架构,其中uint16_t(-1) 导致位掩码1111 1111 1111 1110
  • @Rocki:不依赖于架构:结果由 C++ 标准保证。如答案所述。
【解决方案2】:

编译器应该给你一个警告,如果你使用-Wconversionvalue 将被截断。

warning: conversion to 'uint16_t {aka short unsigned int}' from 'uint32_t {aka unsigned int}' may alter its value [-Wconversion]
uint16_t low1 = value;
                  ^

使用位掩码 g++ 不会产生警告...

【讨论】:

  • 虽然是真的,但这并不能回答问题是否需要位掩码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 2019-02-17
  • 1970-01-01
  • 2021-04-23
  • 2019-10-16
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多