宏定义中双重否定的目的是什么,如(!!(expr))?

可能重复:
C ++代码中的双重否定。

我正在阅读代码库,并找到这样的东西:

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

我无法弄清楚为什么(!!(expr))而不是单个(expr) 。 无论如何,双重否定意味着积极,不是吗? 我错过了什么吗?

这是一种将表达式转换为bool的方法。 但是在C ++中,运营商! 可以超载。 C / C ++的另一种方式:

 0 != (expr) 

仅限C ++方式:

 static_cast(expr) 

[编辑]考虑更多关于C ++运算符重载的问题,避免使用运算符是有意义的。 像Boost.Spirit和Boost.Lambda这样的库使用表达式模板和延迟评估,因此像(expr) || call()这样的(expr) || call() (expr) || call()行为可能与预期不符。 该宏的最防弹版本如下所示:

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

这里,仅使用expr到bool的转换。 需要else分支来保护表达式,如uassert(x) else something_else();

它只会确保宏的expr部分转换为bool。

它有时在C ++中用于转换为布尔类型。

在你向我们展示的例子中, !! 完全没用。 但是,一般来说,它被用作前C99粗略等效于转换为_Bool ,即0保持为0,任何其他值变为1。