c - (x | y) - y 为什么不能简单地是 x 甚至 `x | 0`

标签 c bit-manipulation

我正在阅读内核代码,在一个地方我看到了 if 里面的一个表达式像这样的语句

if (value == (SPINLOCK_SHARED | 1) - 1) {
         ............
}

哪里SPINLOCK_SHARED = 0x80000000是一个预定义的常数。

我想知道为什么我们需要 (SPINLOCK_SHARED | 1) - 1 - 用于类型转换?表达式的结果将是 80000000-- 与 0x80000000 相同,不是吗?然而,为什么 ORing 1 和 Subtracting 1 很重要?

有一种感觉,我想得到一些东西..

最佳答案

这样做只是为了清楚起见,仅此而已。这是因为 atomic_fetchadd_int()(例如 sys/spinlock2.h)在加法/减法之前返回值,并且该值被传递给 _spin_lock_contested()

请注意,C 编译器会完全预先计算所有常量表达式。事实上,编译器甚至可以根据使用传入过程参数的条件来优化内联代码,当过程在这些参数中传递常量时。这就是为什么 sys/lock.h 中的内联 lockmgr() 有一个 case 语句......因为整个 case 语句将被优化并转化为对适当函数的直接调用。

此外,在所有这些锁定函数中,原子操作的开销使所有其他计算相形见绌两个或三个数量级。

-马特

关于c - (x | y) - y 为什么不能简单地是 x 甚至 `x | 0`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59409664/

相关文章:

c - 在 C 中使用 getc() 函数出现未知逻辑错误

c - fscanf 在循环中保存到同一个数组会导致空间填充数组

c++ - GCC 的 __builtin_expect 能走多远?

c - 指向已转换指针的指针?

c - union 和位掩码,这是如何工作的?

java - 如何在不使用 "%"运算符的情况下计算两个数字的余数/模?

python - 如何构建符合 PEP384 的 Python 扩展模块并使用正确的 ABI3 标签对其进行打包?

java - Java中字符串的两个字符互相替换

java - 如何使用位操作实现 Karatsuba 乘法

c++ - 我如何取消设置二进制字符串中的第 k 个设置位