if (mask & VALUE) 或 if ((mask & VALUE) == VALUE)?

发布于 2024-10-10 23:48:33 字数 523 浏览 0 评论 0原文

您可能熟悉 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

谁许谁一生繁华 2024-10-17 23:48:33

构造 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.

醉南桥 2024-10-17 23:48:33

当它用于位集时,您必须只比较单个位,可以使用if(mask & value)

但是,假设您有一个 IP 地址存储在 ant int32 上,并且您想知道它是否是 192.168.*,那么您必须执行以下操作:

if((ip & 0xFFFF0000) == 0xC0A80000) // assuming some endianness representation.

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 is 192.168.*, then you will have to do:

if((ip & 0xFFFF0000) == 0xC0A80000) // assuming some endianness representation.
云仙小弟 2024-10-17 23:48:33

如果结果非零,则您的条件为真。在您的示例中,两个操作的结果将是相同的,第二个选项甚至可能会稍快一些,因为某些 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.

疧_╮線 2024-10-17 23:48:33

即使对于这些语句实际上等效的单位值,我也总是赞成显式比较。

  1. 它使意图更加清晰。我们真的对比较标志感兴趣。 (x & Flag) == Flag 是一个既定的模式,我可以在眨眼之间处理和识别它。

  2. 我通常更喜欢显式转换而不是隐式转换。我对失败状态做了例外处理(例如,我编写 if (file) 而不是 if (file.good())),但在处理数字时,0 不是“失败状态”,它是一个与其他数字一样的数字。我不喜欢在布尔上下文中以不同的方式对待它。

Even for the single-bit value where these statements are actually equivalent, I always favour the explicit comparison.

  1. 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.

  2. I usually prefer explicit over implicit conversions. I make an exception for fail states (e.g. I write if (file) instead of if (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.

笑叹一世浮沉 2024-10-17 23:48:33

if 采用布尔值 (bool)。前一个表达式直接是 bool 类型,而后者是一个数值,将隐式转换为 bool 类型。

if takes a boolean (bool). The former expression is directly of type bool, whereas the latter is a numeric value which will be implicitly converted to bool.

江心雾 2024-10-17 23:48:33

第一个构造,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_REQUIREDFLAG_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:

  • For FLAG_WITH_EXACTLY_ONE_BIT_SET, both cases work.
  • For OBSOLETE_FLAG_SET_TO_ZERO, the first case always returns false.
  • For FLAG_WITH_MULTIPLE_BITS_REQUIRED, or FLAG_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文