8

Possible Duplicate:
Double Negation in C++ code.

I'm reading a code base, and find something like this:

#define uassert(msgid, msg, expr) (void)((!!(expr))||(uasserted(msgid, msg), 0))

I cannot figure out why (!!(expr)) is used instead of a single (expr). Anyway, a double negative means positive, is not it? Am I missing something?

Community
  • 1
  • 1
Fan
  • 1,133
  • 1
  • 9
  • 14
  • I cannot even figure out what's the purpose of this code! ;) – BlackBear Feb 05 '11 at 23:10
  • Like R says, it's completely useless here. – GManNickG Feb 05 '11 at 23:30
  • it's redundant in this case as you yourself have correctly pointed out. Maybe it was just added to avoid some compiler warning. – AndersK Feb 05 '11 at 23:37
  • @AndersK. You are right. It is probably added to satisfy some compiler. As @R and @GMan pointed out, although it is a way to force a bool conversation, the _!!_ trick is not needed here. Because it is already in a bool context. I am clear about it now. Thanks. – Fan Feb 05 '11 at 23:53
  • '-' is negate; '!' is not. "negative" and "positive" do not apply here. Using incorrect terminology sows confusion. – Jim Balter Feb 08 '11 at 09:20

4 Answers4

6

It is a way to cast an expression to bool. In C++ though, operator! can be overloaded. Another way for C/C++:

0 != (expr)

C++ only way:

static_cast<bool>(expr)

[Edit] Thinking more about C++ operator overloading, it make sense to avoid using operators. Libraries like Boost.Spirit and Boost.Lambda use expression templates and lazy evaluation, so that expressions like (expr) || call() may behave not as expected. The most bullet proof version of that macro looks like this:

#define uassert(expr) if(expr) {} else { uasserted(...); }

Here, only conversion of expr to bool is used. The else branch is needed to protect from expressions like uassert(x) else something_else();.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
1

It will just make sure that the expr part of the macro is converted to a bool.

Ray Dey
  • 865
  • 2
  • 11
  • 21
  • @GMan, generally yes, but perhaps not. It's possible that there is no implicit conversion to `bool` but there's an overloaded negation. – Steven Sudit Feb 06 '11 at 01:43
  • @Steven: Someone who writes such a class is an idiot. Sorry, I don't base my practices off what someone dumb might possibly write. – GManNickG Feb 06 '11 at 04:04
  • @GMan: That may well be the case. Nonetheless, the distinction is built into the language. – Steven Sudit Feb 06 '11 at 04:11
1

It is an idiom sometimes used in C++ for converting to a boolean type.

Nic Strong
  • 6,532
  • 4
  • 35
  • 50
1

In the example you showed us, the !! is utterly useless. However, in general it's used as a pre-C99 rough equivalent to casting to _Bool, i.e. 0 stays 0 and any other value becomes 1.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 1
    `!!` is not quite useless. `(expr) || uasserted(...)` may not work as expected in C++ if `||` is an overloaded operator. This is why (expr) must be explicitly cast to boolean first. – Maxim Egorushkin Feb 05 '11 at 23:57
  • Thank you for reminding me why I hate languages with operator overloading (or at least ones where the operators that should have fixed definitions in terms of other operators can be overloaded). – R.. GitHub STOP HELPING ICE Feb 06 '11 at 00:06
  • 1
    @Maxim: Awful reasoning. Observe: `!!` may not work as expected in C++ if `!` is an overloaded operator. Your argument is self-defeating: yes, someone can be moronic with operators, you can't conveniently ignore they could do the same to your position. It's useless for any orthodox program, who cares about the unorthodox crap people write? Base your practices off *good* code, so you end up having *good* programming practices. – GManNickG Feb 06 '11 at 04:06