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

A P*_*son 35 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)
Run Code Online (Sandbox Code Playgroud)

是我能找到的一些例子.

使用!!(condition)结束有什么好处(condition)吗?

Sha*_*our 34

好吧,如果您正在应用的变量!!不是bool(零或一),那么它会将值规范化0或者1.

关于__builtin_expect这个内核,新手线程讨论了符号,其中一个响应解释了(强调我的):

__builtin_expect的签名

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

long __builtin_expect(long exp,long c)

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

对于参考C99 bool宏展开 _Bool,true扩展到1false扩大到0.标准部分草案7.16 类型和值中给出了详细信息.

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

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


Kei*_*son 6

如果操作数等于零,则!应用于任何标量的一元逻辑否定运算符在其操作数不为零时产生该int值.引用标准:01

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

!值相同的标量值应用两次会产生如果值为false则为false的结果,如果值为true则为true,但结果将分别标准化为01.

在大多数情况下,这不是必需的,因为任何标量值都可以直接用作条件.但在某些情况下,你实际上需要一个0或一个1值.

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