Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flags, enum (C)

Tags:

I'm not very used to programming with flags, but I think I just found a situation where they'd be useful:

I've got a couple of objects that register themselves as listeners to certain events. What events they register for is dependent on a variable that is sent to them when they are constructed. I think a nice way to do this would be to send bitwise OR connected variables, like such: TAKES_DAMAGE | GRABBABLE | LIQUID, etc. Then, in the constructor, the object can check what flags are set and register it self as listener for the ones that are.

But this is where I get confused. Preferably, the flags would be in an enum. But that is also a problem. If we have got these flags:

enum
{
    TAKES_DAMAGE,/* (0) */
    GRABBABLE, /* (1) */
    LIQUID, /* (2) */
    SOME_OTHER /* (3) */
};

Then sending the flag SOME_OTHER (3) will be the same as sending GRABBABLE | LIQUID, will it not?

How exactly do you deal with this stuff?

like image 503
quano Avatar asked Oct 27 '09 14:10

quano


People also ask

What are enum flags?

Enum Flags Attribute The idea of Enum Flags is to take an enumeration variable and allow it hold multiple values. It should be used whenever the enum represents a collection of flags, rather than representing a single value. Such enumeration collections are usually manipulated using bitwise operators.

Can enum be treated as set of flags?

Definition. Indicates that an enumeration can be treated as a bit field; that is, a set of flags.

Can enum have float values in C?

Enums can only be ints, not floats in C# and presumably unityScript.


1 Answers

Your enumeration needs to be powers of two :

enum
{
    TAKES_DAMAGE = 1,
    GRABBABLE = 2,
    LIQUID = 4,
    SOME_OTHER = 8
};

Or in a more readable fashion :

enum
{
    TAKES_DAMAGE = 1 << 0,
    GRABBABLE = 1 << 1,
    LIQUID = 1 << 2,
    SOME_OTHER = 1 << 3
};

Why ? Because you want to be able to combine flags with no overlapping, and also be able to do this:

if(myVar & GRABBABLE)
{
    // grabbable code
}

... Which works if the enumeration values look like this :

 TAKES_DAMAGE: 00000001
 GRABBABLE:    00000010
 LIQUID:       00000100
 SOME_OTHER:   00001000

So, say you've set myVar to GRABBABLE | TAKES_DAMAGE, here's how it works when you need to check for the GRABBABLE flag:

 myVar:     00000011
 GRABBABLE: 00000010 [AND]
 -------------------
            00000010 // non-zero => converts to true

If you'd set myVar to LIQUID | SOME_OTHER, the operation would have resulted in :

 myVar:     00001100
 GRABBABLE: 00000010 [AND]
 -------------------
            00000000 // zero => converts to false
like image 169
KeatsPeeks Avatar answered Sep 24 '22 22:09

KeatsPeeks