C语言中意外的位移位行为

C语言中意外的位移位行为,c,undefined-behavior,bit-shift,C,Undefined Behavior,Bit Shift,我目前正试图从一个名为addr的地址中提取一些位,并将一个名为mask的32位掩码提取到另一个名为result的变量中,如下所示 int addr = 7; int x = 0; uint32_t mask = 0xFFFFFFFF; result = addr & (mask >> (32 - x)); 当x=0时,我希望结果为0,这在在线位移计算器上得到了证实。然而,在C代码中,结果是1。为什么会这样?来自C标准(6.5.7位移位运算符) 3对每个操作数执行整数提升。这

我目前正试图从一个名为
addr
的地址中提取一些位,并将一个名为
mask
的32位掩码提取到另一个名为
result
的变量中,如下所示

int addr = 7;
int x = 0;
uint32_t mask = 0xFFFFFFFF;
result = addr & (mask >> (32 - x));
当x=0时,我希望结果为0,这在在线位移计算器上得到了证实。然而,在C代码中,
结果
是1。为什么会这样?

来自C标准(6.5.7位移位运算符)

3对每个操作数执行整数提升。这个 结果的类型是提升的左操作数的类型。如果值 右操作数的值为负或大于或等于 提升左操作数的宽度,行为未定义


您正在执行非法的位移位

按大于或等于左操作数的位大小的值移位会导致错误。这在以下文件的第6.5.7p3节中有记录:

对每个操作数执行整数提升。类型 结果的一部分是提升的左操作数的结果。如果 右操作数为负或大于或等于宽度 对于提升的左操作数,行为未定义

这意味着您需要检查x的值,如果它是0,那么就使用0作为位掩码

int x = 0;
uint32_t mask = 0xFFFFFFFF;
...
if (x == 0) {
    result = 0;
} else {
    result = addr & (mask >> (32 - x));
}

该行为未定义。如果右操作数的值为负数,或大于或等于提升后的左操作数的宽度,则行为未定义。
addr
的类型是什么?这类问题将大大受益于@hyde为什么?没有它是很清楚的。应该是复制品though@EugeneSh. 你是对的@Clifford如果
x
为1,则我们有
mask>>31
=
0xffffff>>31
==1我需要更多睡眠(注释已删除)!另一种选择是添加&((mask>>(31-x))>>1)那么检查x==0是不必要的(我认为-仍然需要睡眠!)