我目前正尝试从地址为addr
的地址中提取一些位,该地址具有一个名为mask
的32位掩码,如下所示,将其提取为另一个名为result
的变量
int addr = 7;
int x = 0;
uint32_t mask = 0xFFFFFFFF;
result = addr & (mask >> (32 - x));
我期望x = 0时结果为0,并且在线移位计算器上已确认了这一点。但是在C代码中,result
是1。为什么?
我目前正尝试从地址为addr
的地址中提取一些位,该地址具有一个名为mask
的32位掩码,如下所示,将其提取为另一个名为result
的变量
int addr = 7;
int x = 0;
uint32_t mask = 0xFFFFFFFF;
result = addr & (mask >> (32 - x));
我期望x = 0时结果为0,并且在线移位计算器上已确认了这一点。但是在C代码中,result
是1。为什么?
您正在执行非法的移位。
移位大于或等于左操作数的位大小的值将导致undefined behavior。 C standard的6.5.7p3节对此进行了记录:
对每个操作数执行整数提升。方式 结果是提升后的左操作数的结果。如果值 右操作数为负或大于或等于宽度 提升后的左操作数,其行为是不确定的。
这意味着您需要检查x的值,如果它是0,则只需使用0作为位掩码。
int x = 0;
uint32_t mask = 0xFFFFFFFF;
...
if (x == 0) {
result = 0;
} else {
result = addr & (mask >> (32 - x));
}
,
根据C标准(6.5.7位移位运算符)
3对每个操作数执行整数提升。的 结果的类型是提升后的左操作数的类型。如果值 右操作数的负数或大于或等于 提升的左操作数的宽度,行为未定义