mahmood
mahmood

Reputation: 24705

on enum and bitwise operation

Maybe the question is so simple...

There is an enum definition:

enum uop_flags_enum {
  FICOMP        = 0x001,  
  FLCOMP        = 0x002,  
  FFCOMP        = 0x004, 
  FMEM          = 0x008, 
  FLOAD         = 0x010, 
  FSTORE        = 0x020, 
  FCTRL         = 0x040, 
  FCALL         = 0x080,  
  FRET          = 0x100, 
  FCOND         = 0x200  
};

Somewhere in the code there is:

if (uop->flags & FCTRL)

When this condition is true and when it is not?

Upvotes: 6

Views: 9299

Answers (6)

jwd
jwd

Reputation: 11114

Ultimately, this code is checking if a single bit (the FCTRL flag) is turned on in the uop->flags variable.

But here's some explanation:

Implicitly, the code if(X) checks for X being a "true" value. For integers, 0 is the only "false" value and everything else is "true".

Therefore your code is equivalent to:

if (0 != (uop->flags & FCTRL))

Now, what does that mean?

The & operator performs a "bitwise AND", which means each bit of the left-hand-side is ANDed with the corresponding bit on the right-hand-side.

So if we wrote out our two operands in binary:

uop->flags      1010 1010  (example)

FCTRL           0100 0000

In this example, if you perform an "AND" on each pair of bits, you get the result:

result          0000 0000

Which evaluates to false, and indeed in that example the uop->flags value does not have the FCTRL flag set.

Now here's another example, where the flag is set:

uop->flags      1110 1010  (example)

FCTRL           0100 0000

The corresponding ANDed result:

result          0100 0000

This result is non-zero, therefore "true", triggering your if statement.

Upvotes: 14

Agnius Vasiliauskas
Agnius Vasiliauskas

Reputation: 11267

In this case each next enum item is shifted by 1 bit left, so it is legal to check if some flag is set by just checking if variable & flag == true. However what if we want to set multi-bit flag pattern ? For example-

enum {
     #ifdef __GNUC__ // cool in GCC we can use binary constants
        myFlag = 0b1010
     #else           // otherwise fallback into integral constant mode
        myFlag = 10
     #endif
}

when how to check if our variable X has this flag set ? We can't just do X & myFlag == true, because for example 0b1000 & myFlag == true and 0b0010 & myFlag == true - but neither 0b1000 nor 0b0010 has our TWO bits set ! For this reason I prefer full checking of bitmask which lets to define multi-bit patterns in enum:

#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)

hth!

Upvotes: 0

Ed Heal
Ed Heal

Reputation: 59997

As the enumerate type is making use of the position of binary digits (i.e. units, 2, 4, 8, 16 etc) and the operation does a logic and. If that bit place is set the value will not be zero (true) otherwise it will be false.

Upvotes: 0

littleadv
littleadv

Reputation: 20272

The condition is true when the bit is set. 0x40 is 1000000, so when the 7th bit in flags is set - it will be true.

Upvotes: 0

Jon
Jon

Reputation: 437336

This is an enum used to define a number of "flags" for an operation. You can deduce this by the fact that every defined value is an exact power of two, and because of this is represented by a single bit ("flag") of a value.

The advantage of this type of enum is that you can combine as many of the flags as you want by using bitwise OR:

uop->flags = FMEM | FLOAD | FRET; // sets the three corresponding flags

The condition you give, which uses bitwise AND

uop->flags & FCTRL

is true if and only if when the FCTRL flag is set, i.e. when the 7th bit of uop->flags is set. This is because FCTRL == 0x040 == binary 01000000.

Upvotes: 5

Lou
Lou

Reputation: 1955

When the bit corresponding to FCTRL (0x040) is set in uop->flags, the condition is true. '&' is a bitwise AND in effect masking all bits but the ones set by FCTRL.

Upvotes: 1

Related Questions