-1

I have seen some code in open source libraries. They check if a particular flag is set in a variable with the test if !!(flag & FLAG1)

My question is why not simply write if (flag & FLAG1) instead? Is the first version more optimized?

T Percival
  • 8,526
  • 3
  • 43
  • 43

3 Answers3

7

It can be used this way:

int a=!!(flag & FLAG1);

If flag & FLAG1 evaluates to 0, then a will be assigned 0. If flag & FLAG1 evaluates to another value, then a will be assigned to 1.

klutt
  • 30,332
  • 17
  • 55
  • 95
1

Without a bit more context it's hard to know the author's reason for doing this, but the most common is that it converts the value to either 0 or 1. This is particularly interesting if you're using __builtin_expect(), in which case yes, it could result in better-optimized code.

It's also used occasionally to make the code a bit more self-documenting… if you see it, you know that you're meant to be treating it as true/false. Usually, when used like this, it's part of a macro.

It's also worth noting that the result is an int, regardless of the original type. This isn't usually consequential, but sometimes it's important.

nemequ
  • 16,623
  • 1
  • 43
  • 62
0

!! is convert to the opposite boolean value, and convert back. The first logical operator will convert whatever return value to the opposite boolean value, and then the second logical operator will convert the opposite value back.

For example:

bool b = !!(flag & FLAG1);

converting flag & FLAG1 return value to a boolean value.

Unless you want to obfuscate your source code, you don’t use this kind of statement. Instead, you can use normal casting to clearly express what you want to do

bool b = (bool)(flag & FLAG1);
msc
  • 33,420
  • 29
  • 119
  • 214
  • 2
    You never explained the reason to use `!!`. – klutt Mar 28 '18 at 05:28
  • The value will be either 0 or 1, but the result of `!` is an `int`, not `_Bool`. – nemequ Mar 28 '18 at 05:30
  • @klutt he meant that fact that OP does not have `(` after if is illegal. It should be written as `if (!!(flag & FLAG1))` –  Mar 28 '18 at 05:37
  • https://port70.net/~nsz/c/c11/n1570.html#6.5.3.3p5 – nemequ Mar 28 '18 at 05:43
  • More importantly, when assigned to an int, it will be either `0` or `1`, and no other value. This can be useful for a `main` function, where the exit code modulo 256 is the shell return value; returning `256` from main is the same as returning `0`, which would not be desired when non-zero indicates error. – T Percival Mar 28 '18 at 05:43