宏定义中双重否定的目的是什么,如(!!(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。