Is !! a safe way to convert to bool in C++?

C++Visual C++Boolean

C++ Problem Overview


[This question is related to but not the same as this one.]

If I try to use values of certain types as boolean expressions, I get a warning. Rather than suppress the warning, I sometimes use the ternary operator (?:) to convert to a bool. Using two not operators (!!) seems to do the same thing.

Here's what I mean:

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?

So, does the double-not technique really do the same thing? Is it any more or less safe than the ternary technique? Is this technique equally safe with non-integral types (e.g., with void * or double for T)?

I'm not asking if !!t is good style. I am asking if it is semantically different than t ? true : false.

C++ Solutions


Solution 1 - C++

The argument of the ! operator and the first argument of the ternary operator are both implicitly converted to bool, so !! and ?: are IMO silly redundant decorations of the cast. I vote for

b = (t != 0);

No implicit conversions.

Solution 2 - C++

Alternatively, you can do this: bool b = (t != 0)

Solution 3 - C++

Careful!

  • A boolean is about truth and falseness.
  • An integer is about whole numbers.

Those are very distinct concepts:

  • Truth and falseness is about deciding stuff.
  • Numbers are about counting stuff.

When bridging those concepts, it should be done explicitly. I like Dima's version best:

b = (t != 0);

That code clearly says: Compare two numbers and store the truth-value in a boolean.

Solution 4 - C++

All valid techniques, all will generate the same code.

Personally, I just disable the warning so I can use the cleanest syntax. Casting to a bool is not something I'm worried about doing accidentally.

Solution 5 - C++


Yes it is safe.


0 is interpreted as false, everthing else is true,
hence !5 comes out as a false
!0 comes out as true
so !!5 comes out as true

Solution 6 - C++

I would not use:

bool b = !!t;

That is the least readable way (and thus the hardest to maintain)

The others depend on the situation.
If you are converting to use in a bool expression only.

bool b = t ? true : false;
if (b)
{
    doSomething();
}

Then I would let the language do it for you:

if (t)
{
    doSomething();
}

If you are actually storing a boolean value. Then first I would wonder why you have a long in the first places that requires the cast. Assuming you need the long and the bool value I would consider all the following depending on the situation.

bool  b = t ? true : false;      // Short and too the point.
                                 // But not everybody groks this especially beginners.
bool  b = (t != 0);              // Gives the exact meaning of what you want to do.
bool  b = static_cast<bool>(t);  // Implies that t has no semantic meaning
                                 // except as a bool in this context.

Summary: Use what provides the most meaning for the context you are in.
Try and make it obvious what you are doing

Solution 7 - C++

I recommend never suppressing that warning, and never using a c cast (bool) to suppress it. The conversions may not always be called as you assume.

There is a difference between an expression that evaluates to true and a boolean of that value.

Both !! and ternary take getting used to, but will do the job similarly, if you do not want to define internal types with overloaded casts to bool.

Dima's approach is fine too, since it assigns the value of an expression to a bool.

Solution 8 - C++

If you're worried about the warning, you can also force the cast: bool b = (bool)t;

Solution 9 - C++

I really hate !!t!!!!!!. It smacks of the worst thing about C and C++, the temptation to be too clever by half with your syntax.

bool b(t != 0); // Is the best way IMHO, it explicitly shows what is happening.

Solution 10 - C++

Comparison to 0 doesn't work so well. Which comes back -- why !! vs. ternary?

class foo { public: explicit operator bool () ; };

foo f;

auto a = f != 0; // invalid operands to binary expression ('foo' and 'int')
auto b = f ? true : false; // ok
auto c = !!f; // ok

Solution 11 - C++

!! may be compact, but I think it is unnecessarily complicated. Better to disable the warning or use the ternary operator, in my opinion.

Solution 12 - C++

I would use b = (0 != t) -- at least any sane person can read it easily. If I would see double dang in the code, I would be pretty much surprised.

Solution 13 - C++

Disable the warning.

Write for clarity first; then profile; then optimize for speed, where required.

Solution 14 - C++

!! is only useful when you're using a boolean expression in arithmetic fashion, e.g.:

c = 3 + !!extra; //3 or 4

(Whose style is a different discussion.) When all you need is a boolean expression, the !! is redundant. Writing

bool b = !!extra;

makes as much sense as:

if (!!extra) { ... }

Solution 15 - C++

I recommend to use

if (x != 0)

or

if (x != NULL)

instead of if(x); it's more understandable and readable.

Solution 16 - C++

The double not feels funny to me and in debug code will be very different than in optimized code.

If you're in love with !! you could always Macro it.

#define LONGTOBOOL(x) (!!(x))

(as an aside, the ternary operator is what I favor in these cases)

Solution 17 - C++

I would use bool b = t and leave the compile warning in, commenting on this particular line's safety. Disabling the warning may bite you in the butt in another part of the code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjwfearnView Question on Stackoverflow
Solution 1 - C++fizzerView Answer on Stackoverflow
Solution 2 - C++DimaView Answer on Stackoverflow
Solution 3 - C++edgar.holleisView Answer on Stackoverflow
Solution 4 - C++Mike FView Answer on Stackoverflow
Solution 5 - C++EvilTeachView Answer on Stackoverflow
Solution 6 - C++Martin YorkView Answer on Stackoverflow
Solution 7 - C++tabdamageView Answer on Stackoverflow
Solution 8 - C++warrenView Answer on Stackoverflow
Solution 9 - C++Jim In TexasView Answer on Stackoverflow
Solution 10 - C++Jay KView Answer on Stackoverflow
Solution 11 - C++Kristopher JohnsonView Answer on Stackoverflow
Solution 12 - C++AlexView Answer on Stackoverflow
Solution 13 - C++Jay BazuziView Answer on Stackoverflow
Solution 14 - C++aibView Answer on Stackoverflow
Solution 15 - C++Marco M.View Answer on Stackoverflow
Solution 16 - C++plinthView Answer on Stackoverflow
Solution 17 - C++Paul NathanView Answer on Stackoverflow