0

I am reading vc crt source code and found following code snippet.

/* Asserts */
/* We use !! below to ensure that any overloaded operators used to evaluate expr do not end up at operator || */
#define _ASSERT_EXPR(expr, msg) \
        (void) ((!!(expr)) || \
                (1 != _CrtDbgReportW(_CRT_ASSERT, _CRT_WIDE(__FILE__), __LINE__, NULL, L"%s", msg)) || \
                (_CrtDbgBreak(), 0))

#ifndef _ASSERT
#define _ASSERT(expr)   _ASSERT_EXPR((expr), NULL)
#endif

I can not understand why do we need !! in the above macro . Could you give a example that a overloaded operator could end up at operator ||?

Jichao
  • 40,341
  • 47
  • 125
  • 198
  • 2
    why downvote without explaination? it's a legitimate question – xmoex Oct 22 '13 at 10:49
  • 2
    a single `!` usually does conversion to `bool`, but negates. Another `!` negates again. With that, `!!` is short hand for cast to `bool`. – stefan Oct 22 '13 at 10:49

1 Answers1

2

Here's an example:

struct Evil {
    int number;
    bool valid;

    operator int() {return number;}
    bool operator!() {return !valid;}
};

Evil evil {42, false};
if (evil)   {std::cout << "It's not zero\n";}
if (!!evil) {std::cout << "It's valid\n";}

In the first case, it's converted to a boolean via the implicit conversion to int, giving true if not zero. In the second, the ! operator gives a different result.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644