I just came onto a project with a pretty huge code base.
I\'m mostly dealing with C++ and a lot of the code they write uses double negation for their boolean logic.
Maybe the programmers were thinking something like this...
!!myAnswer is boolean. In context, it should become boolean, but I just love to bang bang things to make sure, because once upon a time there was a mysterious bug that bit me, and bang bang, I killed it.
It side-steps a compiler warning. Try this:
int _tmain(int argc, _TCHAR* argv[])
{
int foo = 5;
bool bar = foo;
bool baz = !!foo;
return 0;
}
The 'bar' line generates a "forcing value to bool 'true' or 'false' (performance warning)" on MSVC++, but the 'baz' line sneaks through fine.
As Marcin mentioned, it might well matter if operator overloading is in play. Otherwise, in C/C++ it doesn't matter except if you're doing one of the following things:
direct comparison to true
(or in C something like a TRUE
macro), which is almost always a bad idea. For example:
if (api.lookup("some-string") == true) {...}
you simply want something converted to a strict 0/1 value. In C++ an assignment to a bool
will do this implicitly (for those things that are implicitly convertible to bool
). In C or if you're dealing with a non-bool variable, this is an idiom that I've seen, but I prefer the (some_variable != 0)
variety myself.
I think in the context of a larger boolean expression it simply clutters things up.
This may be an example of the double-bang trick, see The Safe Bool Idiom for more details. Here I summarize the first page of the article.
In C++ there are a number of ways to provide Boolean tests for classes.
An obvious way is
operator bool
conversion operator.
// operator bool version
class Testable {
bool ok_;
public:
explicit Testable(bool b=true):ok_(b) {}
operator bool() const { // use bool conversion operator
return ok_;
}
};
We can test the class,
Testable test;
if (test)
std::cout << "Yes, test is working!\n";
else
std::cout << "No, test is not working!\n";
However, opereator bool
is considered unsafe because it allows nonsensical operations such as test << 1;
or int i=test
.
Using
operator!
is safer because we avoid implicit conversion or overloading issues.
The implementation is trivial,
bool operator!() const { // use operator!
return !ok_;
}
The two idiomatic ways to test Testable
object are
Testable test;
if (!!test)
std::cout << "Yes, test is working!\n";
if (!test2) {
std::cout << "No, test2 is not working!\n";
The first version if (!!test)
is what some people call the double-bang trick.
It's a technique to avoid writing (variable != 0) - i.e. to convert from whatever type it is to a bool.
IMO Code like this has no place in systems that need to be maintained - because it is not immediately readable code (hence the question in the first place).
Code must be legible - otherwise you leave a time debt legacy for the future - as it takes time to understand something that is needlessly convoluted.
Yes it is correct and no you are not missing something. !!
is a conversion to bool. See this question for more discussion.