为什么对小于 4 个字节的整数类型的位操作会发生意外行为?

Why does bit operation on integer types smaller than 4 bytes behave unexpectedly?

本文关键字:意外 位操作 类型 小于 整数 字节 为什么      更新时间:2023-10-16

请考虑代码示例,其中我想检查是否设置了无符号整数变量中的所有位。IntegerType替换为uint8_t、uint16_t uint32_t uint64_t。

问题:为什么断言在 IntegerType = uint32_t 和 uint64_t 时成功,而对于 uint16_t 和uint8_t失败?

#include <cstdint>
#include <cassert>
IntegerType bitset = -1; // set all bits to true
IntegerType t = ~bitset;
bool bAllBitsSet1 = (t == 0);
bool bAllBitsSet2 = ((~bitset) == 0);
assert(bAllBitsSet1 == bAllBitsSet2);

这是由于整数提升而发生的:第一个表达式将~bitset转换回较短的类型,而第二个表达式使用完整的整数值。

对于小于int的整数类型,该值在执行操作之前(在本例中(将提升为int,在本例中,在对其应用~之前。

uint16_t为例。当你写的时候

uint16_t t = ~bitset;

bitset的值被提升为int,因此它在32位平台上变得0x0000FFFF。然后应用~,产生0xFFFF0000。最后,结果被写回t,砍掉高位。因此,t为零。

另一方面,当您直接将~bitset与零进行比较时,比较会失败,因为0xFFFF0000不为零。