[编码风格] 在 C-Style 语言中,在表达式的结果前面加 两个感叹号 是什么鬼?

陪她去流浪 桃子 2016年09月06日 编辑 阅读次数:3815

今天一同事在查看我之前写的代码时,发现我代码中有很多地方使用了如下这种两个感叹号的写法:

bool hide = !! luaL_optinteger(L, 2);

,他很好奇我这种写法到底有什么作用。哈哈,个人习惯,看下面的例子。

int main()
{
    int n1 = 123;
    int n2 = 0;
    int n3 = -123;

    bool b1 = n1;           // true,这是第 7 行
    bool b2 = (bool)n1;     // true,这是第 8 行
    bool b3 = !!n1;         // true

    bool b4 = !!n2;         // false
    bool b5 = !!n3;         // true

    return 0;
}

,其实,光从结果来看,结果是正确的。无一例外地正确。

但是,我这个人有点代码洁癖,容不下一个警告。如上的代码,在用 Visual Studio 的各个版本编译时,都会有类似如下的警告产生:

1>  source.cpp(7): warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning)
1>  source.cpp(8): warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning)

VS 给出了一个性能警告,当把 “int” 转换到 “bool” 时。我不知道这会有什么性能问题。没有深究。但奇怪的是:直接把 “int” 赋值给 “bool” 和 使用 C语言风格的强制类型转换均会有警告,挺奇怪的。于是就出现了我经常使用的“两个感叹号”的用法。

在 C-Style 语言中,“!”代表逻辑非,其结果为布尔类型。在整数中,除了“0”逻辑非得 true 以外,其它所有值逻辑非运算后都是得 false。所以,为了与原值的实际布尔值相同,故再取一次非运算,“0”取两次逻辑非得 false,其它值取两次逻辑非得 true,正好保持了原语言的逻辑一致性。故有了“!!”这种看起来有些奇怪的写法。

不管怎样,我认为这应该算是个好习惯吧。

标签:C语言 · C++ · 编码风格