Reputation: 24705
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
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
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
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
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
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
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