也许这个问题很简单......
有一个枚举定义:
enum uop_flags_enum {
FICOMP = 0x001,
FLCOMP = 0x002,
FFCOMP = 0x004,
FMEM = 0x008,
FLOAD = 0x010,
FSTORE = 0x020,
FCTRL = 0x040,
FCALL = 0x080,
FRET = 0x100,
FCOND = 0x200
};
代码中的某处有:
if (uop->flags & FCTRL)
当这个条件为真时,它不是吗?
答案 0 :(得分:14)
最终,此代码检查uop->flags
变量中是否打开了一个位(FCTRL标志)。
但是这里有一些解释:
隐式地,代码if(X)
检查X是否为“真”值。
对于整数,0是唯一的“假”值,其他一切都是“真”。
因此,您的代码相当于:
if (0 != (uop->flags & FCTRL))
现在,这是什么意思?
&
运算符执行“按位AND”,这意味着左侧的每个位与右侧的相应位进行AND运算。
所以如果我们用二进制写出我们的两个操作数:
uop->flags 1010 1010 (example)
FCTRL 0100 0000
在此示例中,如果对每对位执行“AND”,则得到结果:
result 0000 0000
评估为false,实际上在该示例中uop->flags
值没有设置FCTRL标志。
现在这是另一个例子,其中标志是设置:
uop->flags 1110 1010 (example)
FCTRL 0100 0000
相应的ANDed结果:
result 0100 0000
此结果为非零,因此为“true”,触发您的if
语句。
答案 1 :(得分:5)
这是一个枚举,用于为操作定义许多“标志”。您可以通过以下事实推断出这一点:每个定义的值都是2的精确幂,因此由值的单个位(“标志”)表示。
此类枚举的优点是您可以使用bitwise OR组合任意数量的标志:
uop->flags = FMEM | FLOAD | FRET; // sets the three corresponding flags
您提供的条件,使用bitwise AND
uop->flags & FCTRL
当且仅当FCTRL
标志置位时,即uop->flags
的第7位置位时,才为真。这是因为FCTRL == 0x040 == binary 01000000。
答案 2 :(得分:1)
当在uop->标志中设置与FCTRL(0x040)对应的位时,条件为真。 '&安培;'是按位AND有效屏蔽所有位,但是由FCTRL设置的位。
答案 3 :(得分:0)
当该位置位时,条件为真。 0x40是1000000,所以当flags
中的第7位置位时 - 它将为真。
答案 4 :(得分:0)
由于枚举类型正在利用二进制数字的位置(即单位,2,4,8,16等),并且操作执行逻辑和。如果设置了该位,则该值不为零(true),否则为false。
答案 5 :(得分:0)
在这种情况下,每个下一个枚举项都向左移1位,因此通过检查是否variable & flag == true
来检查是否设置了某个标志是合法的。但是,如果我们想设置多位标志模式呢?例如 -
enum {
#ifdef __GNUC__ // cool in GCC we can use binary constants
myFlag = 0b1010
#else // otherwise fallback into integral constant mode
myFlag = 10
#endif
}
何时检查我们的变量X是否设置了此标志?我们做不到
X & myFlag == true
,因为例如0b1000 & myFlag == true
和0b0010 & myFlag == true
- 但0b1000和0b0010都没有设置我们的TWO位!出于这个原因,我更喜欢完全检查位掩码,以便在枚举中定义多位模式:
#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)
HTH!