Home > Mobile >  Casting invalid value to an enum via static_cast
Casting invalid value to an enum via static_cast

Time:08-04

Doesn't static_cast protect against 'invalid' values to the type it's being cast to i.e Values here?

If so, it's not a good idea to print the casted value? How to ensure the print only takes place once the value is correct/valid?

enum class Values : uint8_t 
{
    One,
    Two
};

void bar(uint8_t value)
{
    Values val = static_cast<Values >(value);
    printf ("The received value = %u\n", val);
    
    switch(val)
    {
       case One:  break;
       case Two:  break;
       default:   break;
    }
}

int main()
{
    bar(static_cast<uint8_t>(60));
}

CodePudding user response:

No, there are no checks and there is nothing wrong with using a static_cast like this, no matter what the value is.

You specified that Values has underlying type uint8_t, so it is perfectly fine to (static_) cast between Values and uint8_t freely. There doesn't need to be a declared enumerator with a given value for the value to be valid for the enumeration. All values of the underlying type are also valid values of the enumeration type.

If you want to assure that the value is one of the enumerators, you need to write a function checking that yourself and decide on how it should act if the value does not satisfy the condition. (Should it throw an exception?)

(The rules are different if you don't specify an underlying type in an unscoped enumeration, in which case there is no fixed underlying type to substitute for uint8_t in the above and not all values of the implementation-defined underlying type are valid for the enumeration.)

CodePudding user response:

No, static_cast does not protect against values that are out of your enum range.

In fact, if you try to cast an 'invalid' value, this will simply result in 'undefined behavior'.

It's best to prevent these issues by using enums everywhere in your code and convert to enum immediately where external data is entering your program. During this conversion you must manually check the incoming integers.

An old trick from C is to add a last enum value, which makes the manual check easy (of course this only works for enums that don't have explicit value and thus range from 0 to N):

enum class Values : uint8_t 
{
    One,
    Two,
    Last,
};
  • Related