khuttun
khuttun

Reputation: 733

Comparing enums to integers

I've read that you shouldn't trust on the underlying implementation of an enum on being either signed or unsigned. From this I have concluded that you should always cast the enum value to the type that it's being compared against. Like this:

enum MyEnum { MY_ENUM_VALUE = 0 };

int i = 1;
if (i > static_cast<int>(MY_ENUM_VALUE))
{
    // do stuff
}

unsigned int u = 2;
if (u > static_cast<unsigned int>(MY_ENUM_VALUE))
{
    // do more stuff
}

Is this the best practice?

Edit: Does the situation change if the enum is anonymous?

Upvotes: 7

Views: 24260

Answers (3)

Alexis Wilke
Alexis Wilke

Reputation: 20720

An enum is an integer so you can compare it against any other integer, and even floats. The compiler will automatically convert both integers to the largest, or the enum to a double before the compare.

Now, if your enumeration is not supposed to represent a number per se, you may want to consider creating a class instead:

enum class some_name { MY_ENUM_VALUE, ... };

int i;
if(i == static_cast<int>(some_name::MY_ENUM_VALUE))
{
    ...
}

In that case you need a cast because an enum class is not viewed as an integer by default. This helps quite a bit to avoid bugs in case you were to misuse an enum value...


Update: also, you can now specify the type of integer of an enum. This was available in older compilers too, but it was often not working quite right (in my own experience).

enum class some_name : uint8_t { ... };

That means the enumeration uses uint8_t to store those values. Practical if you are using enumeration values in a structure used to send data over a network or save in a binary file where you need to know the exact size of the data.

When not specified, the type defaults to int.


As brought up by others, if the point of using enum is just to declare numbers, then using constexpr is probably better.

constexpr int MY_CONSTANT_VALUE = 0;

This has the same effect, only the type of MY_CONSTANT_VALUE is now an int. You could go a little further and use typedef as in:

typedef int my_type_t;
constexpr my_type_t MY_CONSTANT_VALUE = 0;

I often use enum even if I'm to use a single value when the value is not generally considered an integer. There is no set in stone rule in this case.

Upvotes: 7

AndersK
AndersK

Reputation: 36082

Best practice is not to write

int i = 1;
if (i > static_cast<int>(MY_ENUM_VALUE))
{
    // do stuff
}

instead write

MyEnumValue i = MY_ENUM_VALUE ;
...
if ( i > MY_ENUM_VALUE ) {..}

But if - as in your example - you only have one value in your enum it is better to declare it as a constant instead of an enum.

Upvotes: -1

Kaidul
Kaidul

Reputation: 15855

Short answer: Yes

enum is signed int type, but they get implicitly cast into unsigned int. Your compiler might give a warning without explicit casting, but its still very commonly used. however you should explicitly cast to make it clear to maintainers.

And of course, explicit cast will be must when its a strongly typed enum.

Upvotes: 3

Related Questions