Couldnt find a relevant answer to my case so i will try explaining my situation:
I have the following code:
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
}
My code is for lexing a document and I am trying to do an action only when i am NOT in a comment block. The thing is that the above statement returns exactly the opposite when i am not in a comment...
the following statement does the job correctly but seems rather counterintuitive:
if (lexStatus & fInCommentBlock == fInCommentBlock)
So the questions are:
Due to operator precedence if ((lexStatus & fInCommentBlock) != fInCommentBlock)
fixes the issue
Last question added because for some reason lexStatus & fInCommentBlock
because some of the bits ARE set even though i dont set them anywhere in the code...
Thanks in advance for your help!
To address your first question: Your problem is operator precedence and understanding of how bitwise operators work.
if (lexStatus & fInCommentBlock == fInCommentBlock)
This works for you only because ==
have higher precedence than &
so fInCommentBlock == fInCommentBlock
is always true, hence the same thing as lexStatus & 1
, which is the same thing as lexStatus & OnlySpaces
. This will be true when lexStatus == initState
because initState
includes flag OnlySpaces
.
Is there a better way?
You want to abstract the bitwise comparison into one or two helper functions.
int LexStatus_Is(int flags) { return (lexStatus & flags) == flags; }
int LexStatus_IsNot(int flags) { return (lexStatus & flags) != flags; }
Then you can write:
if (LexStatus_IsNot(fInComment))
Which would be more intuitive.