为什么要将标志与位掩码和标志的按位与的结果进行比较?

Why compare a flag with the result of bitwise AND of a bitmask and the flag?

作为“How to use bitmask": When I want to test if a certain flag is set in a given bitmask, I would usually do so solely through the usage of a bitwise AND:

的后续
if(bitmask & flag) { …

然而我经常看到这样的事情:

if((bitmask & flag) == flag) { …

这是我在强类型语言和弱类型语言上观察到的情况,这排除了对类型转换灾难的某种预防措施。我能想到的唯一两个测试不等效的场景是,如果 flag 碰巧设置了不止一位,并且需要 all 是在 bitmask 中设置条件通过。这是全部还是我在这里遗漏了什么?

奖励:编译器是否有办法识别 flag 在运行时最多设置一位并优化(可能是伪造的)比较?

正如您所指出的,这两个条件并不等同。检查 (bitmask & flag)1 正在检查 flag 中设置的 any 位是否在 bitmask 中设置,而(bitmask & flag) == flag 检查是否设置了 flag 中的 所有 位。

在只有一个位设置的情况下,您可能还会在 Java 等没有从整数类型到布尔值的隐式转换的语言中看到第二种形式而不是第一种形式。这些语言中第一次检查的确切等价物是 (bitmask & flag) != 0,即使检查单个标志,该形式也可能更规范。

就实际生成的代码而言,大部分都是学术性的。

对于编译时已知的2 标志,编译器可以看到该标志只有一位,两种形式通常都会编译为 identical code - 查看 fixedAfixedB 中的函数 link.

对于具有未知标志的函数,如前所述,形式并不相同,因此代码不同(请参阅 unknownAB 函数)但性能差异非常小。


1 或者,等效地,(bitmask & flag) != 0 在没有从整数类型到布尔值的隐式转换的语言中。

2 重要的是,这包括接受变量标志但调用者使用常量标志且函数是内联的函数。