How to Use Enums as Flags in C++

Flags, enum (C)

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

How to use enums as flags in C++?

The "correct" way is to define bit operators for the enum, as:

enum AnimalFlags
{
HasClaws = 1,
CanFly = 2,
EatsFish = 4,
Endangered = 8
};

inline AnimalFlags operator|(AnimalFlags a, AnimalFlags b)
{
return static_cast<AnimalFlags>(static_cast<int>(a) | static_cast<int>(b));
}

Etc. rest of the bit operators. Modify as needed if the enum range exceeds int range.

How to use C++11 enum class for flags

You need to write your own overloaded operator| (and presumably operator& etc.).

Flags operator|(Flags lhs, Flags rhs) 
{
return static_cast<Flags>(static_cast<char>(lhs) | static_cast<char>(rhs));
}

Conversion of an integer to an enumeration type (scoped or not) is well-defined as long as the value is within the range of enumeration values (and UB otherwise; [expr.static.cast]/p10). For enums with fixed underlying types (this includes all scoped enums; [dcl.enum]/p5), the range of enumeration values is the same as the range of values of the underlying type ([dcl.enum]/p8). The rules are trickier if the underlying type is not fixed - so don't do it :)

What does the [Flags] Enum Attribute mean in C#?

The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value. Such collections are often used with bitwise operators, for example:

var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;

Note that the [Flags] attribute doesn't enable this by itself - all it does is allow a nice representation by the .ToString() method:

enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
[Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }

...

var str1 = (Suits.Spades | Suits.Diamonds).ToString();
// "5"
var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();
// "Spades, Diamonds"

It is also important to note that [Flags] does not automatically make the enum values powers of two. If you omit the numeric values, the enum will not work as one might expect in bitwise operations, because by default the values start with 0 and increment.

Incorrect declaration:

[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}

The values, if declared this way, will be Yellow = 0, Green = 1, Red = 2, Blue = 3. This will render it useless as flags.

Here's an example of a correct declaration:

[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}

To retrieve the distinct values in your property, one can do this:

if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}

or prior to .NET 4:

if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}

if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}

Under the covers

This works because you used powers of two in your enumeration. Under the covers, your enumeration values look like this in binary ones and zeros:

 Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000

Similarly, after you've set your property AllowedColors to Red, Green and Blue using the binary bitwise OR | operator, AllowedColors looks like this:

myProperties.AllowedColors: 00001110

So when you retrieve the value you are actually performing bitwise AND & on the values:

myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!

The None = 0 value

And regarding the use of 0 in your enumeration, quoting from MSDN:

[Flags]
public enum MyColors
{
None = 0,
....
}

Use None as the name of the flag enumerated constant whose value is zero. You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. However, you can perform a logical, not a bitwise, comparison between the numeric value and the None enumerated constant to determine whether any bits in the numeric value are set.

You can find more info about the flags attribute and its usage at msdn and designing flags at msdn

How to use enums with bit flags

Yes, use bitwise OR (|) to set multiple flags:

ColorType pinkColor = kWhite | kRed;

Then use bitwise AND (&) to test if a flag is set:

if ( pinkColor & kRed )
{
// do something
}

The result of & has any bit set only if the same bit is set in both operands. Since the only bit in kRed is bit 1, the result will be 0 if the other operand doesn't have this bit set too.

If you need to get whether a particular flag is set as a BOOL rather than just testing it in an if condition immediately, compare the result of the bitwise AND to the tested bit:

BOOL hasRed = ((pinkColor & kRed) == kRed);

Is there any reason to use enum params over bit flags in c#?

They have different meanings. Flags are characterised by the fact that it's meaningful to OR them together; enums are simply discrete lumps of data, and the fact that they are numerical under the covers is nothing more than an implementation detail.

If you use flags where it's not meaningful to OR two of them together, you will badly mislead anyone who comes to use your data type. Conversely, if you use an enum where you meant a flag, then you'll have to manually capture and name exponentially many enum cases.

Enum with flag and Bitwise operation

Two of your requirements make it impossible to use a bitwise flags enum for this purpose.

  • There is no way to represent the order in which bits were set.
  • There is no way to represent a bit being set more that once.

All of these actions are indistinguishable when using a bitwise flag enum:

Added, Edited, Reordered
Added, Reordered, Edited
Added, Edited, Reordered, Edited

They are all represented as Added | Edited | Reordered.

As mentioned in comments, you should instead use a List<State> to represent this data.

Flags and operation on enums? C#

Behind the scenes, the enumeration is actually an int.

<< is the Bitwise Left Shift Operator

An equivalent way of writing this code is :

[Flags]
public enum EAccountStatus
{
None = 0,
FreeServiceApproved = 1,
GovernmentAccount = 2,
PrivateOrganisationAccount = 4,
All = 8
}

Please note, that this enumeration has the Flag attribute

As stated in the msdn:

Use the FlagsAttribute custom attribute for an enumeration only if a
bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a
numeric value.

This way, if you want to have multiple options set you can use:

var combined =  EAccountStatus.FreeServiceApproved  | EAccountStatus.GovernmentAccount 

which is equivalent to:

  00000001  // =1 - FreeServiceApproved 
| 00000010 // =2 - GovernmentAccount
---------
00000011 //= 3 - FreeServiceApproved and GovernmentAccount

this SO thread has a rather good explanation about the flags attribute

A replace to enum flags in C

You should review static const vs #define in C.

It sounds as if you are using enumerations of the general form:

enum
{
FLAG_A = 0x00000001, FLAG_B = 0x00000002, FLAG_C = 0x00000004, FLAG_D = 0x00000008,
...
};

You also combine these various enumeration values into a (32-bit) unsigned int value with bitwise operations.
Now you've reached the limit; you have more than 32 flags (and I trust they're more meaningfully named than in my example).

You could decide to start a new series of enumerations, using a second 32-bit (unsigned) integer to store the bits. This has the merit of keeping the symbols in the debuggable program (unlike #define constants which are seldom available even in debuggable programs). The downside is that you might need to pass two values where previously you passed one.

If it is imperative to keep the flags in a single variable, you'll need to review whether it is better to use an unsigned long long, or perhaps a structure with two unsigned int values would work.

I agree that it is better not to use bitfields, though they might work sufficiently well. I would also go to considerable pains to avoid using #define, and would probably use either two 32-bit variables or a structure. A lot depends on your code base, and how extensively the values will be used.



Related Topics



Leave a reply



Submit