1

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:

  • Why? Why is it acting totally the opposite to what i am expecting?

Due to operator precedence if ((lexStatus & fInCommentBlock) != fInCommentBlock) fixes the issue

  • Am i approaching the correct way?
  • Is there a better way?
  • Is there a way to make sure each flag has a distinct value?

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!

RaptorX
  • 331
  • 1
  • 9
  • 19
  • 3
    What's wrong with just `if (lexStatus & fInCommentBlock)` ? – Pavel Radzivilovsky Nov 02 '12 at 23:21
  • always returns true... : LexStatus = 10, fInCommentBlock = 118, LexStatus & fInCommentBlock = 2 – RaptorX Nov 02 '12 at 23:22
  • `fInCommentBlock == fInCommentBlock` is always going to return true also, right? – evanmcdonnal Nov 02 '12 at 23:24
  • 3
    I'm not sure this is the cause, but: Operator precedence? Is `lexStatus & fInCommentBlock != fInCommentBlock` the same thing as `(lexStatus & fInCommentBlock) != fInCommentBlock`? – Simon Forsberg Nov 02 '12 at 23:25
  • indeed that makes it work as intended... didnt noticed that it could affect it. The other two questions are still standing though – RaptorX Nov 02 '12 at 23:28
  • What are you trying to do? What are the state values, and what condition do you check for? – Pavel Radzivilovsky Nov 02 '12 at 23:31
  • (lexStatus & fInCommentBlock) will only be non zero if any of the bits set in fInCommentBlock is set - I think you need to have a bit mask which represents the state in a single bit to avoid the comparison – Caribou Nov 02 '12 at 23:31
  • I am just starting right now and one of the states im checking for is where i am NOT inside a comment block, and that can be defined in this particular language as a valid comment flag only followed by spaces which is what that flag attempts to indicate and I am not using that flag yet so it should be always false at the moment. @Caribou why isnt the way im assigning it a unique value? is there a way to make sure i get unique ids for those enums? – RaptorX Nov 02 '12 at 23:35
  • @RaptorX thats not quite what I meant - let me check the numbers and I'll post or apologise - sometimes I jump the gun :) – Caribou Nov 02 '12 at 23:41
  • @RaptorX See my answer I grabed your enum and generated a simple prog to get the bit masks because it's late and I'm tired - but it illustates what I mean I think. – Caribou Nov 02 '12 at 23:58
  • Time for bed - sorry for confusing people - – Caribou Nov 03 '12 at 00:22

1 Answers1

4

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.

Oskar N.
  • 8,427
  • 2
  • 23
  • 21