FrozenHeart
FrozenHeart

Reputation: 20746

reinterpret_cast error for enum

Why i can't use reinterpret_cast operator for such a cast?

enum Foo { bar, baz };

void foo(Foo)
{
}

int main()
{
   // foo(0); // error: invalid conversion from 'int' to 'Foo'
   // foo(reinterpret_cast<Foo>(0)); // error: invalid cast from type 'int' to type 'Foo'
   foo(static_cast<Foo>(0)); 
   foo((Foo)0);
}

Upvotes: 14

Views: 5905

Answers (4)

IS4
IS4

Reputation: 13197

reinterpret_cast is used only for pointers, to be able to convert between the address and an integral type, or between two otherwise incompatible pointer types.

However, if you absolutely wish to use reinterpret_cast for enums, you can! You can do reinterpret_cast<Foo&>(value) or, in this case reinterpret_cast<const Foo&>(static_cast<const std::underlying_type_t<Foo>&>(0)). This is a well-defined operation, resulting in *reinterpret_cast<Foo*>(&value). This works because std::underlying_type_t<Foo> is either signed or unsigned type corresponding to Foo and thus accessible through the pointer.

Upvotes: 0

alfC
alfC

Reputation: 16242

Other answers fail to get to the point directly. Despite being a bad use of reinterpret_cast, compilation fails because you can't apply reinterpret_cast on values directly. You can apply it only to convert pointers of reference expressions. (in particular, it can't convert literal constants.)

So this compiles,

enum Foo { bar, baz };

void foo(Foo)
{
}

int main()
{
   // foo(0);
   int zero = 0;
   foo(reinterpret_cast<Foo&>(zero)); // error: invalid cast from type 'int' to type 'Foo'
   foo(static_cast<Foo>(0)); 
   foo((Foo)0);
}

https://godbolt.org/z/x6MP1e5eo

Upvotes: 0

Travis Gockel
Travis Gockel

Reputation: 27633

I think that reinterpret_cast can be use for all types of casts, because it's force any type casts to another type with all side-effects of this conversion.

That is a common misconception. Conversions which can be performed with reinterpret_cast are listed explicitly in 5.2.10 of the standard. int-to-enum and enum-to-int conversions are not in the list:

  • Pointer to integral type, so long as the integer is large enough to hold it
  • nullptr_t to integer
  • integral type or enum to pointer
  • function pointer to another function pointer of different type
  • object pointer to another object pointer of different type
  • nullptr_t to other pointer type
  • pointer-to-member of T1 to a different pointer-to-member of T2 in cases where both T1 and T2 are objects or functions

reinterpret_cast is typically used to tell the compiler: Hey, I know you think this region of memory is a T, but I'd like you to interpret it as a U (where T and U are unrelated types).

It is also worth noting that reinterpret_cast can have effects on the bits:

5.2.10.3

[ Note: The mapping performed by reinterpret_cast might, or might not, produce a representation dif- ferent from the original value. — end note ]

The C-style cast always works, because it included static_cast in its attempts.

Upvotes: 24

Rost
Rost

Reputation: 9089

Because regular enum underlying type is int, there is nothing to reinterpret. Static cast is proper conversion for this case.

Upvotes: 4

Related Questions