Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of a double negative in macro definition, like (!!(expr))? [duplicate]

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?

like image 754
Fan Avatar asked Feb 05 '11 23:02

Fan


People also ask

Why do we define %1 and %2 in macro?

The first parameter symbol is %1 , the second is %2 , and so on. You pass values for the parameters when you reference the macro symbol name for expansion. Macro parameter values are character sequences of no formal type, and they are comma delimited. There is no way to pass in a comma as part of a parameter value.

What is the function of macros?

A macro is an automated input sequence that imitates keystrokes or mouse actions. A macro is typically used to replace a repetitive series of keyboard and mouse actions and used often in spreadsheets and word processing applications like MS Excel and MS Word.

Can I #define in a macro?

Macros using #define A macro is a fragment of code that is given a name. You can define a macro in C using the #define preprocessor directive. Here's an example.

What is a function-like macro?

More complex than object-like macros, a function-like macro definition declares the names of formal parameters within parentheses, separated by commas. An empty formal parameter list is legal: such a macro can be used to simulate a function that takes no arguments.


1 Answers

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();.

like image 108
Maxim Egorushkin Avatar answered Sep 18 '22 12:09

Maxim Egorushkin