25

I have an enum declaration using bit flags and I cant exactly figure out on how to use this.

enum 
{
  kWhite   = 0,
  kBlue    = 1 << 0,
  kRed     = 1 << 1,
  kYellow  = 1 << 2,
  kBrown   = 1 << 3,
};
typedef char ColorType;

I suppose to store multiple colors in one colorType I should OR the bits together?

ColorType pinkColor = kWhite | kRed;

But suppose I would want to check if pinkColor contains kRed, how would I do this?

Anyone care to give me an example using the provided ColorType example ?

Oysio
  • 3,486
  • 6
  • 45
  • 54

1 Answers1

33

Yes, use bitwise OR (|) to set multiple flags:

ColorType pinkColor = kWhite | kRed;

Then use bitwise AND (&) to test if a flag is set:

if ( pinkColor & kRed )
{
   // do something
}

The result of & has any bit set only if the same bit is set in both operands. Since the only bit in kRed is bit 1, the result will be 0 if the other operand doesn't have this bit set too.

If you need to get whether a particular flag is set as a BOOL rather than just testing it in an if condition immediately, compare the result of the bitwise AND to the tested bit:

BOOL hasRed = ((pinkColor & kRed) == kRed);
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
walkytalky
  • 9,453
  • 2
  • 36
  • 44
  • 19
    Note: This means that if `pinkColor` is `kRed`, `(pinkColor & kRed)` will evaluate to `kRed`, *not* 1 or `YES`! This can be a pitfall when assigning to a small type such as `BOOL`: If the value is 1 << (number of bits in a `BOOL`) or greater, it will be out of range. A common fix is to compare the result to the tested bit: `BOOL isPink = ((pinkColor & kRed) == kRed);` An alternative is to cast the result to C99's `bool` type: `isPink = (bool)(pinkColor & kRed);` And a(n admittedly uncommon) way that doesn't assume 1 is in range would use `?:`: `isPink = (pinkColor & kRed) ? YES : NO;` – Peter Hosey Aug 20 '10 at 06:06
  • @PeterHosey Relevant further reading for anyone interested in your comment: http://www.bignerdranch.com/blog/bools-sharp-corners/. By the way, if anyone is confused (as I was) about why on earth casting to a C99 `bool` instead of `BOOL` fixes the problem, the answer is that casts to `bool` are magic, as discussed in http://stackoverflow.com/questions/16934876/magic-of-casting-value-to-bool. The short version is: `bool` is an alias of `_Bool` and the C99 standard says *"When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1."* – Mark Amery May 08 '14 at 21:51