在将uint64_t截断为uint8_t[I]时,我应该使用位掩码吗

Should I use a bit mask when truncating uint64_t to uint8_t[i]?

本文关键字:我应该 掩码 uint64 uint8 在将      更新时间:2023-10-16

如果我有一个大int,比如一个uint64_t和一个uint 8_t数组,例如:

uint64_t large = 12345678901234567890;
uint8_t small[5];

我想把uint64_t的8个最低有效位复制到uint8_t数组的一个元素中,只使用安全吗

small[3] = large;

或者我应该使用位掩码:

small[3] = large & 255;

即,是否存在大int的其余部分可能以某种方式溢出到数组的其他元素中的情况?

它肯定不会导致数据处理错误。但是,某些编译器可能会生成警告消息。

有两种选择可以避免这种情况。

您可以投射您的变量:

(uint8_t)large

或者您可以禁用警告:

#pragma warning(disable:4503)

我建议强制转换变量,因为隐藏编译器警告可能会使您无法发现实际问题,因此不是最佳做法。

这是完全安全的

small[3] = large;

并且在[conv.integral]:中明确描述了这种转换

如果目标类型是无符号的,则得到的值是与源一致的最小无符号整数整数(模2n,其中n是用于表示无符号类型的位数)。

也就是说,这四个语句都保证最终在small[3]:中具有相同的值

small[3] = large;
small[3] = large % 256;
small[3] = large & 255;
small[3] = static_cast<uint8_t>(large);

没有函数上的理由来执行%&或强制转换自己,尽管如果你无论如何都想这样做,如果编译器没有为这四个代码(gcc和clang-do)生成相同的代码,我会感到惊讶。

一个区别是,如果使用类似-Wconversion的东西进行编译,这将导致发出警告(有时这可能是有益的)。在这种情况下,你会想做演员。