在C语言中,很多运算都会用到位移位,其中经常使用整数字面量。例如,考虑以下代码片段:
#define test_bit(n, flag) (1UL << (n) & (flag))
恕我直言,整数文字“UL”应该抑制不需要的移位,例如对有符号整数进行符号扩展可能会导致设置多个位。但是,如果是这样,只进行逻辑左移,如上所示,我们还需要整数文字吗?
由于左移不会导致意外行为,所以我无法弄清楚它的目的是什么。像上面这样的代码经常出现在Linux内核等项目中,我想肯定有这个需求,有谁知道这种情况下整数字面量的用途吗?
如果您的
int
是 32 位,并且您有 `
#define test_bit(n, flag) ((1 << (n)) & (flag))
然后
test_bit(n, 31)
由于有符号整数溢出而具有未定义的行为。 为什么无符号整数溢出定义了行为,而有符号整数溢出则不然?
将
1
设置为无符号类型可以避免 UB。使其成为 unsigned long
(这就是 1UL
实现的目标)允许将相同的宏用于更宽的蒙版。例如,在 int
为 32 位且 long
为 64 位的系统上,通过使用 1UL
,您可以安全地使用 test_bit(n, 63)
之前的位。