3

I have been seeing people writing code like

SomeType c=....

    if(!!c)
    {
     ....
    }

in what circumstance, would it be difference from

if (c)
{
   .....
}
Peaceful
  • 472
  • 5
  • 13
  • When `c` isn't a `bool` (with a `true` or `false` value at least). – chris Jul 09 '14 at 15:38
  • 1
    [Operator overloading](http://en.cppreference.com/w/cpp/language/operators). – BoBTFish Jul 09 '14 at 15:38
  • so this means it is acutally same as if(c == true), which can also do the conversion of c to a bool – Peaceful Jul 09 '14 at 15:39
  • @chris Well, they would be the same for an `int` too. – BoBTFish Jul 09 '14 at 15:39
  • I think it's the same as `if ((bool)c)` as well. – Max Jul 09 '14 at 15:39
  • @BoBTFish, Yeah, I didn't pay attention to the context too much. It would differ if the numerical value was used. – chris Jul 09 '14 at 15:40
  • If there's ever a discrepancy between those two forms, that's a sign of bad coding. – David G Jul 09 '14 at 15:40
  • Note that this is one of the cases where an expression is "contextually converted to bool", so `if(X)` is considered the same as `if((bool)X)`. (This works even if `X` has an **`explicit`** conversion to `bool`). – BoBTFish Jul 09 '14 at 15:40
  • @Max, As long as a conversion from `SomeType` to `bool` exists. – chris Jul 09 '14 at 15:40
  • @KKKoo0 No, for integers `(c == true)` checks whether `(c == 1)` (the `true` is promoted to an integer, rather than `c` to being demoted to a boolean). –  Jul 09 '14 at 15:43
  • @chris indeed, this can be [used to normalize to 0 or 1](http://stackoverflow.com/a/20916491/1708801). – Shafik Yaghmour Jul 09 '14 at 15:44
  • Before C++11, one might define `operator!` to give some kind of "validness" test, but not define `operator bool` since that could cause confusing implicit conversions to numeric types. In that case, you'd need `!!` to express "valid". (These days, `explicit operator bool` does the job nicely.) – Mike Seymour Jul 09 '14 at 16:08

2 Answers2

4

This practice originates from the C language. Before C had a boolean type.

When c is 0, !!c is also 0.

When c is any other value, !!c is always 1.

This converts c into a true 2-state boolean. Testing expressions like ( !!bool1 == !!bool2 ) or ( !!bool3 == TRUE ) will give the expected result, even if these values are different bitwise representations of "true".

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
0

I've found that the following generates a warning in Microsoft Visual C++:

int i = GetSomeValue();
bool b = (bool) i;

warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)

My intent is clear but the compiler insists on generating the warning. If I use the double negation then the warning goes away.

int i = GetSomeValue();
bool b = !!i;
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622