为什么用!!(条件)代替(条件)?

时间:2014-01-04 03:27:57

标签: c logical-operators

我见过人们使用带有两个'!'的条件子句的代码

#define check_bit(var, pos)       (!!((var) & (1 << (pos))))
#define likely(x)       __builtin_expect(!!(x),1)
#define unlikely(x)     __builtin_expect(!!(x),0)

是我能找到的一些例子。

使用!!(condition)优于(condition)是否有任何好处?

4 个答案:

答案 0 :(得分:33)

如果您应用的变量!!不是bool零或一个),那么它将规范化该值到01

关于__builtin_expectkernel newbies thread讨论了符号,其中一个回复解释了(强调我的):

  

__builtin_expect的签名

     

http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html)是:

     

long __builtin_expect(long exp,long c)

     

请注意,exp参数应该是一个整数表达式,因此没有指针   或那里的浮点类型。 双重否定处理来自的转换   这些类型自动为积分表达式。这样,就可以了   写:可能(ptr)而不是可能(ptr!= NULL)

C99 bool中的参考宏扩展为_Booltrue扩展为1false扩展为{{ 1}}。详细信息在标准草案部分0 布尔类型和值中给出。

5 段落中的7.16 一元算术运算符涵盖了逻辑否定:

  

逻辑否定运算符的结果!如果其操作数的值比较,则为0   不等于0,1如果其操作数的值比较等于0.结果的类型为int。   表达式!E等价于(0 == E)。

答案 1 :(得分:6)

应用于任何标量的一元!逻辑否定运算符如果操作数非零,则生成int0,如果操作数相等则生成1为零。引用标准:

  

表达式!E相当于(0==E)

!两次应用于相同的标量值会产生如果值为false则为false的结果,如果值为true则为true - 但结果将标准化为0或{{1}分别。

在大多数情况下,这不是必需的,因为任何标量值都可以直接用作条件。但在某些情况下,您实际上需要10值。

在C99或更高版本中,将表达式转换为1(或_Bool,如果bool具有相同的行为,可能会被认为更清晰。但是(a)结果是类型#include <stdbool.h>而不是_Bool,以及(b)如果您使用的是不支持int的C99前编译器,并且您已定义了自己的_Bool类型,它的行为方式与C99的bool不同。

答案 2 :(得分:4)

我能看到的最大值是,它会强制(或规范化)值10(这是一个布尔值),无论x或{的方式如何{1}}表达式展开(例如varchardouble等。)

答案 3 :(得分:2)

它转换为布尔值,有时可能很有用。