if (mask & VALUE) 或 if ((mask & VALUE) == VALUE)?
您可能熟悉 enum
位掩码方案,例如:
enum Flags {
FLAG1 = 0x1,
FLAG2 = 0x2,
FLAG3 = 0x4,
FLAG4 = 0x8,
NO_FLAGS = 0,
ALL_FLAGS = FLAG1 | FLAG2 | FLAG3 | FLAG4
};
f(FLAG2 | FLAG4);
我见过很多代码,然后测试掩码中的某个位,例如
if ((mask & FLAG3) == FLAG3)
但这不是等价的吗?
if (mask & FLAG3)
使用第一个版本有什么理由吗?在我看来,第二个较短的版本更清晰。
也许是 C 程序员遗留下来的习惯,认为真值应该转换为 1
? (尽管如此,较长的版本在赋值或 return 语句中比在条件语句测试中更有意义。)
You're probably familiar with the enum
bitmask scheme, like:
enum Flags {
FLAG1 = 0x1,
FLAG2 = 0x2,
FLAG3 = 0x4,
FLAG4 = 0x8,
NO_FLAGS = 0,
ALL_FLAGS = FLAG1 | FLAG2 | FLAG3 | FLAG4
};
f(FLAG2 | FLAG4);
I've seen a lot of code that then tests for a certain bit in the mask like
if ((mask & FLAG3) == FLAG3)
But isn't that equivalent to this?
if (mask & FLAG3)
Is there some reason to use the first version? In my opinion, the second shorter version is more legible.
Maybe leftover habits from C programmers who think true values should be converted to 1
? (Though even there, the longer version makes more sense in an assignment or return
statement than in a conditional statement test.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
构造
if ((mask & FLAG3) == FLAG3)
测试 FLAG3 中的所有位是否出现在 mask 中;if (mask & FLAG3)
测试是否存在any。如果您知道 FLAG3 正好设置了 1 位,则它们是等效的,但如果您可能定义复合条件,那么养成显式测试所有位的习惯可能会更清楚(如果这就是您的意思)。
The construct
if ((mask & FLAG3) == FLAG3)
tests if all bits in FLAG3 are present in mask;if (mask & FLAG3)
tests if any are present.If you know FLAG3 has exactly 1 bit set, they are equivalent, but if you are potentially defining compound conditions, it can be clearer to get into the habit of explicitly testing for all bits, if that's what you mean.
当它用于位集时,您必须只比较单个位,可以使用
if(mask & value)
。但是,假设您有一个 IP 地址存储在 ant
int32
上,并且您想知道它是否是192.168.*
,那么您必须执行以下操作:When it is for a bitset, so you have to compare just a single bit, it is okay to have
if(mask & value)
.But, suppose that you have an IP address stored on ant
int32
and you want to know whether it is192.168.*
, then you will have to do:如果结果非零,则您的条件为真。在您的示例中,两个操作的结果将是相同的,第二个选项甚至可能会稍快一些,因为某些 CPU 可以比其他任意数字更容易地测试零,但是:
显然,如果值您正在检查的内容包含多个位。在这种情况下,您必须使用第一个选项。如果您同时检查多个位,这显然也适用。
Your condition will be true if the result is non-zero. In your example, the result of both operations would be equivalent, and the second option could even be slightly faster because some CPUs can test for zero easier than other arbitrary numbers, BUT:
Obviously, you can't do the second option if the value you're checking for consists of more than one bit. In that case, you have to use the first option. That obviously also applies if you're checking for several bits at the same time.
即使对于这些语句实际上等效的单位值,我也总是赞成显式比较。
它使意图更加清晰。我们真的有对比较标志感兴趣。
(x & Flag) == Flag
是一个既定的模式,我可以在眨眼之间处理和识别它。我通常更喜欢显式转换而不是隐式转换。我对失败状态做了例外处理(例如,我编写
if (file)
而不是if (file.good())
),但在处理数字时,0 不是“失败状态”,它是一个与其他数字一样的数字。我不喜欢在布尔上下文中以不同的方式对待它。Even for the single-bit value where these statements are actually equivalent, I always favour the explicit comparison.
It makes the intent clearer. We really are interested in comparing flags.
(x & Flag) == Flag
is an established pattern and I can process and recognize it at the blink of an eye.I usually prefer explicit over implicit conversions. I make an exception for fail states (e.g. I write
if (file)
instead ofif (file.good())
) but when working with numbers, 0 is not a “fail state”, it’s a number like any others. I don’t like treating it differently in a boolean context.if
采用布尔值 (bool
)。前一个表达式直接是bool
类型,而后者是一个数值,将隐式转换为bool
类型。if
takes a boolean (bool
). The former expression is directly of typebool
, whereas the latter is a numeric value which will be implicitly converted tobool
.第一个构造,
if (mask & FLAG3)
表示“如果标志和掩码中至少有一个公共位”。例如,如果格式和supported_formats之间有任何位相同,则if (formats &supported_formats)
为真。第二个结构,
if (mask & FLAG3) == FLAG3
表示“如果 FLAG3 中的所有设置位都在掩码中设置”。例如,如果 所有 things_required 都在 things_you_have 中,则if (things_you_have & things_required) == things_required
将为 true。以下是一些特殊情况的快速介绍:
FLAG_WITH_EXACTLY_ONE_BIT_SET
,两种情况都有效。OBSOLETE_FLAG_SET_TO_ZERO
,第一种情况始终返回 false。FLAG_WITH_MULTIPLE_BITS_REQUIRED
或FLAG_WHICH_IS_REALLY_TWO_FLAGS_COMBINED_WITH_AN_OR
,第一种情况不应该返回 true。第二种情况正确返回。如果您遇到 FLAG_WITH_EXACTLY_ONE_BIT_SET 的情况,则应该使用第二个构造进行编码,以避免标志值更改时出现奇怪的问题。除非你的分析器告诉你要挤出每一个操作,否则要明确。
The first construct,
if (mask & FLAG3)
means "if at least one common bit is in the flag and mask". For example,if (formats & supported_formats)
would be true if any bit were in common between formats and supported_formats.The second construct,
if (mask & FLAG3) == FLAG3
means "if all set bits in FLAG3 are set in the mask". For example,if (things_you_have & things_required) == things_required
would be true if all things_required were in things_you_have.Here's a quick hit of some special cases:
FLAG_WITH_EXACTLY_ONE_BIT_SET
, both cases work.OBSOLETE_FLAG_SET_TO_ZERO
, the first case always returns false.FLAG_WITH_MULTIPLE_BITS_REQUIRED
, orFLAG_WHICH_IS_REALLY_TWO_FLAGS_COMBINED_WITH_AN_OR
, the first case returns true when it should not. The second case returns correctly.If you have the case of a FLAG_WITH_EXACTLY_ONE_BIT_SET, you should code with the second construct to avoid strange problems when the flag value gets changed. Be explicit unless your profiler tells you to squeeze out every operation.