【问题标题】:What does !!(x) mean in C (esp. the Linux kernel)?!!(x)在C(尤其是Linux内核)中是什么意思?
【发布时间】:2011-02-01 09:29:06
【问题描述】:

我一直在阅读 Linux 内核(特别是 2.6.11)。 我遇到了以下定义:

#define unlikely(x)     __builtin_expect(!!(x), 0)

(来自 linux-2.6.11/include/linux/compiler.h:61 lxr link

什么 !!完成?为什么不直接使用 (x)?

另见:

【问题讨论】:

标签: c gcc


【解决方案1】:

!!(x) 强制它为 0 或 1。0 仍为 0,但任何非零值(在布尔上下文中为“真”)都变为 1。

【讨论】:

  • 在这种情况下实际上没有必要,因为我们希望结果为 0。实际上只有 #define likely(x) __builtin_expect(!!(x), 1) 需要确保 true 为 1。它可能只包含在 unlikely 定义中为了对称。
  • 多么有趣,我之前使用过x&&1(或ObjC 中的x&&YES)。从未想过使用!!
【解决方案2】:

与其说是一种语言语法,不如说是一种将 char 或 int 转换为准布尔值的常用简写。

在 C 逻辑运算中,例如 == && !等等可以作用于 int、char 等,因为没有布尔类型,但是根据标准,它们保证返回 0 表示 False 和 1 表示 true。

例如,如果你有

int x = 5;

您可以强制它转换为“布尔”类型(C 中没有布尔类型,因此使用引号)

x = !x; /* !5 which gives 0 always */
x = !x; /* which gives 1 always */

【讨论】:

  • 事实上 C 确实有一个布尔类型。 _Bool 是在 C99 中引入的,<stdbool.h> 中的宏 bool 扩展为 _Bool。但是像==&&! 等内置逻辑运算符仍然会产生int 类型的结果,其值为01
  • "但是根据标准,它们保证返回 0 表示 False 和 1 表示真。"你确定吗?我认为任何非零都是真的,这允许编译器优化返回非 1 值来表示“真”。
【解决方案3】:

!!(x) 等价于 (x) != 0(除非在 C++ 中进行了一些非常奇怪的运算符重载)。

!!(x) 在做什么并不明显这一事实可能是使用(x) != 0 的一个很好的理由。除非你想成为精英内核黑客。

请参阅this closed question(如果它还在的话)讨论!! 的优点(也许这个问题会被重新打开,因为这个问题表明它有一些价值)。

【讨论】:

  • 第一次看到!!(x) 半秒钟的行为“并不明显”。在您看到它并且 a) 考虑一下或 b) 询问其他人之后,您会很快认识到 !!“操作员”的作用。
  • @Chris - 如果它是您商店中的常见习语,则可以使用它。另一方面,我很少遇到!!(x),以至于我不得不暂停片刻才能了解它。关于(x) != 0 的含义,我无需费解。没什么大不了的,但我觉得!!(x)(x) != 0 更值得推荐。
  • 很公平。我更喜欢它的外观,但在 (x) != 0 上使用它并没有真正令人信服的论据(除非您需要依赖一些重载 ! 的对象来在布尔上下文中评估它们)。
猜你喜欢
  • 2012-03-29
  • 2018-01-14
  • 2012-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多