m69*_*g'' 8 c++ arrays int bit-manipulation type-conversion
如果我有一个大的int,比如一个uint64_t和一个uint8_t数组,例如:
uint64_t large = 12345678901234567890;
uint8_t small[5];
Run Code Online (Sandbox Code Playgroud)
我想将8个最低有效位复制uint64_t到数组的元素中uint8_t,使用是否安全:
small[3] = large;
Run Code Online (Sandbox Code Playgroud)
或者我应该使用位掩码:
small[3] = large & 255;
Run Code Online (Sandbox Code Playgroud)
即是否有任何情况,其中大型int的其余部分可能以某种方式溢出到数组的其他元素?
肯定不会导致数据处理不正确。但是,某些编译器可能会生成警告消息。
有两种选择可以避免这些情况。
您可以强制转换变量:
(uint8_t)large
Run Code Online (Sandbox Code Playgroud)
或者您可以禁用警告:
#pragma warning(disable:4503)
Run Code Online (Sandbox Code Playgroud)
我建议强制转换该变量,因为隐藏编译器警告可能会阻止您发现实际问题,因此不是最佳实践。
这是完全安全的:
small[3] = large;
Run Code Online (Sandbox Code Playgroud)
这种转换在 [conv.integral] 中明确描述:
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2 n,其中 n 是用于表示无符号类型的位数)。
也就是说,这四个语句都保证最终得到相同的值small[3]:
small[3] = large;
small[3] = large % 256;
small[3] = large & 255;
small[3] = static_cast<uint8_t>(large);
Run Code Online (Sandbox Code Playgroud)
没有功能上的理由需要自己进行%or&或 转换,但如果你想这样做的话,如果编译器没有为所有四个生成相同的代码(gcc 和 clang 都会生成),我会感到惊讶。
一个区别是,如果您使用类似的东西进行编译-Wconversion,这会导致发出警告(有时这可能是有益的)。在这种情况下,你会想要进行演员阵容。