是否有一种直观的方式检查标志和状态

Is there an intuitive way of checking for flags and states?

本文关键字:方式 检查 标志 状态 直观 一种 是否      更新时间:2023-10-16

无法找到我案件的相关答案,因此我将尝试解释我的情况:

我有以下代码:

enum Flags {
    OnlySpaces      = 1 <<  0,
    valComment      = 1 <<  1,
    valCommentBlock = 1 <<  2,
    valLabelName    = 1 <<  3,
    valVariableName = 1 <<  4,
    valFunctionName = 1 <<  5,
    invSyntax       = 1 << 32,
    fInVarLab       = valLabelName|valVariableName,
    fInIdentifier   = valLabelName|valVariableName|valFunctionName,
    fInCommentBlock = OnlySpaces|valCommentBlock,
    initState       = OnlySpaces|fInIdentifier|valComment,
};
int lexStatus = initState;
for (int i = 0; sc.More(); sc.Forward(), i++) {
    if (sc.atLineStart) {
        if (lexStatus & fInCommentBlock != fInCommentBlock) // Here is the problem
            sc.SetState(DEFAULT);
        lexStatus = initState;
    }
 ... // More code
 }

我的代码是为了征求文档,我只有在不在评论块中时才能做一个操作。问题是,当我不在评论中,上述语句完全返回相反的情况...

以下语句正确地完成了工作,但似乎违反直觉:

if (lexStatus & fInCommentBlock == fInCommentBlock)

所以问题是:

  • 为什么?为什么它的行为与我的期望完全相反?

由于操作员优先级,if ((lexStatus & fInCommentBlock) != fInCommentBlock)解决了问题

  • 我正在以正确的方式接近吗?
  • 有更好的方法吗?
  • 有没有办法确保每个标志具有独特的值?

添加了最后一个问题,因为出于某种原因lexStatus & fInCommentBlock,因为设置了某些位,即使我不在代码中的任何地方设置它们...

预先感谢您的帮助!

解决您的第一个问题:您的问题是操作员的优先级和对位运算符的工作方式的理解。

if (lexStatus & fInCommentBlock == fInCommentBlock)

这仅是因为==&具有更高的优先级,因此fInCommentBlock == fInCommentBlock始终是正确的,因此与lexStatus & 1相同,这与lexStatus & OnlySpaces是相同的。当lexStatus == initState时,这将是正确的,因为initState包括标志OnlySpaces

有更好的方法吗?

您想将位比较抽象为一个或两个辅助功能。

int LexStatus_Is(int flags) { return (lexStatus & flags) == flags; }
int LexStatus_IsNot(int flags) { return (lexStatus & flags) != flags; }

然后您可以写:

if (LexStatus_IsNot(fInComment))

更直观。