q0987
q0987

Reputation: 35982

Does this C++ casting to enum have problems?

Given the following code:

enum Options
{
    Surf     = 0x01,
    Out      = 0x02
};

Options all = (Options) ( Surf | Out);
  1. Does this casting have problems?
  2. If this casting make sense, then why?

Based on my understanding, Options only defines two variables. How does the value 0x03 makes sense?

Upvotes: 4

Views: 1262

Answers (5)

James McNellis
James McNellis

Reputation: 355069

Does this casting have problems?

No.

If this casting make sense, then why? Based on my understanding, Options only defines two variables, how the value 0x03 makes sense?

The enumeration type Options has two named enumerators, but the range of values that it represents is large enough that it can be used as a bitfield containing each of the enumerators.

In short: yes, it is valid and well-defined to use an enumeration for a bitfield like this.

As requested in the comments to this answer, the formal language permitting this can be found in the C++ Standard (C++03 7.2/6):

For an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values of the underlying type in the range bmin to bmax, where bmin and bmax are, respectively, the smallest and largest values of the smallest bit-field that can store emin and emax.

It is possible to define an enumeration that has values not defined by any of its enumerators.

There is some debate as to whether or not this is good style. Certainly it can be argued that it is often assumed that an enumeration object can only store one of its enumerators, so code like this could be confusing and error-prone.

On the other hand, I would argue that it is usually quite obvious when an enumeration is intended for use as a bitfield. Usually such an enumeration is named with an Options or Flags suffix or something similar. Likewise, if each of the enumerators has a set value that is clearly a single set bit, that enumeration is probably intended for use as a bitfield.

Upvotes: 7

Mark Ransom
Mark Ransom

Reputation: 308206

You might get away with assigning an arbitrary integer value to an enum type variable, but it's bad style. As always, code for readability first, and the compiler second. The expectation is that an enum variable will only hold valid enumeration constants.

I would change the last line to:

int all = ( Surf | Out); 

Upvotes: 0

Jesus Ramos
Jesus Ramos

Reputation: 23268

enums are just placeholders for int values so when you bitwise or them you get this : in binary (4 bit representation so its easier for me): 0001 | 0010 = 0011 or 3. Enums can be any value even completely invalid ones.

Upvotes: 0

david van brink
david van brink

Reputation: 3642

Apart from some syntax troubles, your code does work. But it's kinda tacky. Enums are ints, but stylewise, you should stick to values that are actually in the enumeration.

Maybe use a different int for the bitwise-collection. & be careful to assign powers of 2, I guess. If you really want a bitwise set.

typedef enum Options
{
Surf     = 0x01,
Out      = 0x02
} Options;

Upvotes: 0

gravitron
gravitron

Reputation: 3604

Q1> Yes. You're using an enum when you seemingly want a bitmask.

Q2> You are correct, it doesn't make sense. Using an enum implies that the variable all would be equal to one of the items in Options, not an or'd combination of multiple items..

Upvotes: 1

Related Questions