我刚刚进入一个拥有相当庞大代码库的项目.
我主要处理C++,他们编写的很多代码都使用布尔逻辑的双重否定.
if (!!variable && (!!api.lookup("some-string"))) {
do_some_stuff();
}
Run Code Online (Sandbox Code Playgroud)
我知道这些人都是聪明的程序员,很明显他们不会偶然这样做.
我不是经验丰富的C++专家,我唯一猜测他们这样做的原因是他们想要绝对肯定被评估的值是实际的布尔表示.所以他们否定它,然后再次否定它以使其恢复到它的实际布尔值.
这是正确的,还是我错过了什么?
对于英特尔架构,是否有一种方法可以指示GCC编译器生成的代码总是强制分支预测在我的代码中采用特定方式?英特尔硬件是否支持此功能?那么其他编译器或硬件呢?
我会在C++代码中使用它,我知道我希望快速运行的情况,并且不关心当另一个分支需要被采取时,即使它最近采用了该分支.
for (;;) {
if (normal) { // How to tell compiler to always branch predict true value?
doSomethingNormal();
} else {
exceptionalCase();
}
}
Run Code Online (Sandbox Code Playgroud)
作为Evdzhan Mustafa的后续问题,该提示是否可以在处理器第一次遇到指令时指定一个提示,所有后续的分支预测都能正常运行?
[这个问题有关,但并不等同于这一个 ]
如果我尝试使用某些类型的值作为布尔表达式,我会收到警告.我有时使用三元运算符(?:)转换为bool 而不是抑制警告.使用两个not运算符(!!)似乎做同样的事情.
这就是我的意思:
typedef long T; // similar warning with void * or double
T t = 0;
bool b = t; // performance warning: forcing 'long' value to 'bool'
b = t ? true : false; // ok
b = !!t; // any different?
Run Code Online (Sandbox Code Playgroud)
那么,双重技术真的做同样的事吗?它比三元技术更安全吗?这是技术与非整数类型(例如,具有同样安全void *或double对T)?
我不是在问好!!t风格.我在问它是否在语义上不同于t ? true : false.
我一直在阅读Linux内核(特别是2.6.11).我发现了以下定义:
#define unlikely(x) __builtin_expect(!!(x), 0)
Run Code Online (Sandbox Code Playgroud)
(来自linux-2.6.11/include/linux/compiler.h:61 lxr链接)
什么!! 完成?为什么不使用(x)?
也可以看看:
我刚刚在Microsoft的guiddef.h头文件中找到了这个:
__inline bool operator==(REFGUID guidOne, REFGUID guidOther)
{
return !!IsEqualGUID(guidOne,guidOther);
}
Run Code Online (Sandbox Code Playgroud)
是否有任何意义!!,或者是某些开发人员那天感觉很可爱?
可能重复:
C++代码中的双重否定
据我所知,没有C/C++书籍教程或手册提到这种技术.也许是因为它只是一个小小的东西,不值得一提.
我使用它是因为C/C++将bool类型与int,long,pointer,double等混合在一起.需要将非bool转换为bool是很常见的.使用(bool)值来做这件事是不安全的,所以我习惯!!这样做.
例:
bool bValue = !!otherValue;
Run Code Online (Sandbox Code Playgroud)