37

I have some C++ code that makes extensive use of !!. I'm kinda baffled because as far as I know !! is not a operator on it's own but two ! after each other. So that would mean that !!foo is the same as just foo.

Is there any place and or reason when !! actually makes sense? I was thinking about if it could perhaps have a bit wise meaning? So you first perform some bit wise operation on foo and then ! on the result? But I don't seem to remember ! being used as a bit wise operator and don't seem to find any reference telling me it is either. As far as I can tell ! in only used as a logical operator and in that case

!!foo == foo

msw
  • 42,753
  • 9
  • 87
  • 112
inquam
  • 12,664
  • 15
  • 61
  • 101
  • 5
    One can also write `x+++++y+1`, but it's a bad idea. – msw Apr 24 '13 at 12:31
  • @GrahamBorland Now I am going to go over there and vote that as a duplicate of this. – Alvin Wong Apr 24 '13 at 13:01
  • You may also like to read this: [*what is !! in c?*](http://stackoverflow.com/questions/14751973/what-is-in-c?lq=1). – Grijesh Chauhan Apr 24 '13 at 17:27
  • @msw no you cannot. modifying more than once between two sequence points is undefined behavior. `!!` is perfectly defined and corresponds to triggering safe bool conversion operators. Which is particularly useful for `optional`, `variant` or any smart pointer. – v.oddou Dec 10 '19 at 10:59

5 Answers5

56

It is not as simple as double negation. For example, if you have x == 5, and then apply two ! operators (!!x), it will become 1 - so, it is used for normalizing boolean values in {0, 1} range.

Note that you can use zero as boolean false, and non-zero for boolean true, but you might need to normalize your result into a 0 or 1, and that is when !! is useful.

It is the same as x != 0 ? 1 : 0.

Also, note that this will not be true if foo is not in {0, 1} set:

!!foo == foo

#include <iostream>

using namespace std;

int main()
{
        int foo = 5;

        if(foo == !!foo)
        {
                cout << "foo == !!foo" << endl;
        }
        else
        {
                cout << "foo != !!foo" << endl;
        }



        return 0;
}

Prints foo != !!foo.

Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91
  • what might be the possible use cases for this? – Koushik Shetty Apr 24 '13 at 12:11
  • 3
    Say you have some place where a bool is stored as a 1 or a 0, in a bit or something. And the value you check against is 5 (which would count as true), you can basically turn that 5 into a 1. – inquam Apr 24 '13 at 12:12
  • bool x = !0; // true bool x = !-15 // false int i = x; Check this out – mtsiakiris Apr 24 '13 at 12:30
  • 4
    A bit more formally, its result is `true`. Values of type `bool` are `true` and `false`. In arithmetic contexts they are converted to `1` and `0`, respectively. – Pete Becker Apr 24 '13 at 12:58
  • 1
    I have used this technique on a compiler that complained when I implicitly cast an `int` to a `bool` (performance warning: value will be converted to 0 or 1). My options are to do a C-style `bool` cast (which I consider to be a bad habit), do `0 != v` (the `?1:0` afterwards is redundant) which creates order of operations ambiguity forcing `()`ing (at least to make it clear what is happening), or `static_cast( v )` which is overly verbose. `!!` casts a type that is implicitly convertible to `bool` to `bool` without warnings and as a unary (and hence tightly bound) operator. – Yakk - Adam Nevraumont Apr 24 '13 at 13:04
  • There are some difference between !!cond and !!(cond) ? – magrif Sep 02 '21 at 11:52
9

It can be used as shorthand to turn foo into a boolean expression. You might want to turn a non-boolean expression into true or false exclusively for some reason.

foo = !!foo is going to turn foo into 1 if it's non-zero, and leave it at 0 if it already is.

Victor Sand
  • 2,270
  • 1
  • 14
  • 32
4

if foo != 0, then !!foo == 1. It is basically a trick to convert to bool.

Avidan Borisov
  • 3,235
  • 4
  • 24
  • 27
3

If foo is not of type bool, then !!foo will be. So !!foo can be 1 or 0.

Tobias Müller
  • 585
  • 1
  • 4
  • 21
2

This technique is used for an safe evaluation of an variable in an boolean context. If you have an normal conversation to bool (operator bool()) unrelated variables (with differnt types) can participate in boolean expressions in an unwanted way. A defintion of operator! which returns a negated boolean value is implemented. And its result has to be negated again. Simply have a look at the Safe bool idiom.

Jan Herrmann
  • 2,717
  • 17
  • 21