Re: Using flags

From: Arthur J. O'Dwyer (ajo_at_nospam.andrew.cmu.edu)
Date: 01/09/05


Date: Sat, 8 Jan 2005 21:52:25 -0500 (EST)


On Sat, 8 Jan 2005, xm wrote:
[re: bitflags]
> As I understand with an (int) I have 16 bit of play.

   15 bits, technically, since plain 'int' is signed and you're not really
allowed to mess around with the sign bit. The real explanation is more
complicated, but it turns out that it doesn't matter, because you should
never used signed types for anything bit-related in C or C++.

   Use 'unsigned int' for a full 16 bits of play, or 'unsigned long' for
32. I recommend 'unsigned long', since on most modern machines it's going
to take 32 bits no matter what you do. Occasionally I find that

     unsigned flags; /* unsigned int, 16 flags' worth */

is clearer and no less useful than

     unsigned long flags; /* 32 flags' worth */

("What's long about them?" thinks the reader), but that's up to you.

> I've seen that I could use flags this way:
>
> SomeFunction(FLAG_ONE | FLAG_TWO | FLAG_THREE)
>
> But could you tell me:
> 1) what would be the definition of SomeFunction()

   void SomeFunction(unsigned long flags);

> 2) what would be the definition of FLAG_ONE, etc...

     #define FLAG_ONE 0x0001
     #define FLAG_TWO 0x0002
     #define FLAG_THREE 0x0004
     #define FLAG_FOUR 0x0008
     #define FLAG_FIVE 0x0010
     [...]

You could also use enums, or in C++ you could even use static const
members of a class, but I'll stick with the old-fashioned way. I like
the #define way because it makes everything line up easily, and doesn't
have those cluttery '=' signs everywhere. :)

> 3) inside SomeFunction(){}, how can I check to see if FLAG_ONE is set,
> etc...
>
> I am not sure, I've had LogicMath course at the university and I guess it
> would be:
>
   void SomeFunc(unsigned long Flags)
   {
> if(Flags & FLAG_ONE == FLAG_ONE){ /*Flag one is set */ }
> else { /* it's not */ }
> }

That will work. It tests all the bits in FLAG_ONE at once, though,
which in this case is irrelevant, but consider

     #define FLAG_ONE 0x0001 /* et cetera, as above */
     #define FLAG_ONE_AND_THREE 0x0005 /* == FLAG_ONE | FLAG_THREE */
     #define FLAG_FOUR_AND_FIVE 0x0018 /* == FLAG_FOUR | FLAG_FIVE */

     void SomeFunction(unsigned long flags)
     {
         if (flags & FLAG_ONE)
           puts("Flag 1 is set.");
         if (flags & FLAG_ONE_AND_THREE)
           puts("At least one of Flags 1 and 3 is set.");
         if (flags & FLAG_ONE_AND_THREE == FLAG_ONE_AND_THREE)
           puts("Both of Flags 1 and 3 are set.");
         if (flags & (FLAG_ONE_AND_THREE | FLAG_FOUR_AND_FIVE))
           puts("At least one of Flags 1, 3, 4, and 5 is set.");
         if (~flags & FLAG_ONE)
           puts("Flag 1 is not set.");
         if (~flags | FLAG_ONE == ~flags)
           puts("Flag 1 is set!");
         flags &= ~FLAG_ONE; /* turns Flag 1 off */
         flags |= FLAG_ONE; /* turns Flag 1 on */
     }

...And so on. Google for a tutorial on bitwise operators if you need a
refresher, but most of what you'll need isn't even pencil-and-paper stuff.

HTH,
-Arthur



Relevant Pages

  • probably leveling Lakhdar Jalali
    ... Occasionally Owen will accumulate the embarrassment, ... They are toping into the council now, ... deaf for Rifaat to matter it. ... Get your promptly driving realm on behalf of my plain. ...
    (sci.crypt)
  • Re: OT - Immediate Withdrawal
    ... >>> breaks out sooner or later no matter what we do. ... >> Even when we have proper security and stable economy installed? ... I said that this is what you need to do, to clean up the mess and THEN ...
    (alt.sports.basketball.nba.la-lakers)
  • Re: Adding large numbers in C
    ... one of the numbers - or perhaps the result - is too big to store in an int. ... But carry /does/ matter. ... The second step is to calculate the carry, storing the result in C: ... Incidentally, the subtraction routine does similar juggling, so if M and N ...
    (comp.lang.c)
  • Re: Serialize/marshal/reverse engineer unknown structure
    ... other language/platform for that matter) to help you". ... I can almost do it portably, though in more complex examples padding ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Run cmd button in code
    ... >>> calling Msgbox.) ... It really doesn't matter. ... Why on earth wouldn't you need to trap errors in a "plain old ...
    (microsoft.public.vb.general.discussion)