Christopher Pisz
Christopher Pisz

Reputation: 4000

Flags - Check if bits are set and only those bits are set

According to other questions on Stack Overflow, we can check if a bit flag is set using:

if(value & flag)

Check if flag is set in integer variable

Checking for bit flags

C/C++ check if one bit is set in, i.e. int variable

However, I want to check if particular flags are set and if only the bits that make up those flags are set.

static const uint64_t SOMEFLAG_0 = 0x0;
static const uint64_t SOMEFLAG_1 = 0x1 << 0;
static const uint64_t SOMEFLAG_2 = 0x1 << 1;
static const uint64_t SOMEFLAG_3 = 0x1 << 2;
static const uint64_t SOMEFLAG_4 = 0x1 << 3;

My attempt was:

if ((value & ~(SOMEFLAG_1 | SOMEFLAG_4)) == 0)

However, that won't work in the case flag 1 is set and flag 4 is not set. I want to test if the are both set and no other bits are set.

How do I perform that test in a conventional manner? Perhaps I want to XOR the value and the mask and do something?

Upvotes: 2

Views: 1620

Answers (2)

bolov
bolov

Reputation: 75688

Sometimes the simplest answer eludes you after having your mind wrapped in complicated things.

This is enough:

if(value == flag)

And if you need to check multiple flags:

if(value == (SOMEFLAG_1 | SOMEFLAG_4))
            ^                       ^
            important               important

And don't forget to enclose the bitwise operations in parenthesis. The precedence is unexpected and without them value == SOMEFLAG_1 would be evaluated first.


And I guess this is a perfect time for preaching for enabling (and paying attention to) compiler warnings:

clang has a very helpful one -Wparentheses which is included in -Wall:

5 : :5:28: warning: | has lower precedence than ==; == will be evaluated first [-Wparentheses]

if(value == SOMEFLAG_1 | SOMEFLAG_4)
   ~~~~~~~~~~~~~~~~~~~~^

5 : :5:28: note: place parentheses around the '==' expression to silence this warning

if(value == SOMEFLAG_1 | SOMEFLAG_4)
                       ^
   (                  )

5 : :5:28: note: place parentheses around the | expression to evaluate it first

if(value == SOMEFLAG_1 | SOMEFLAG_4)
                       ^
            (                      )

gcc has it also:

5 : :5:14: warning: suggest parentheses around comparison in operand of '|' [-Wparentheses]

 if(value == SOMEFLAG_1 | SOMEFLAG_4)
    ~~~~~~^~~~~~~~~~~~~

Upvotes: 6

Louis Langholtz
Louis Langholtz

Reputation: 3123

You almost have it. It's:

if ((value & (SOMEFLAG_1 | SOMEFLAG_4)) == (SOMEFLAG_1 | SOMEFLAG_4))

Of course this assumes you don't care what SOMEFLAG2 or 3 are. If that's also the case (that you care about all bits), then:

if (value == (SOMEFLAG_1 | SOMEFLAG_4))

Upvotes: 1

Related Questions