简体   繁体   中英

C-style cast of enum class to reference of underlying type char

Is this legal C++ (>=14), resulting in a char being read and saved into aCode ?

enum class ECode : char { Code1 = 'a' };
std::istream& operator>>(std::istream& aIn, ECode& aCode)
{
  return aIn >> (std::underlying_type_t<ECode>&)aCode;
}

I would prefer return aIn >> static_cast<std::underlying_type_t<ECode>&>(aCode) which is not legal, it seems ("cannot cast to reference of unrelated type".)

However, this very similar line is legal, and is what my C-style cast should be identical to:

return aIn >> *static_cast<char*>(static_cast<void*>(&aCode))

As has been noted in comments, there is no strict aliasing violation because char can alias any type.

In practice I doubt any real compiler would do anything other than the "obvious" implementation, ie give the enum the same size and representation as the underlying type. In which case your reinterpret_cast would be well-defined and behave as expected.

However the Standard (as of C++17) does not appear to guarantee that.

As far as I can see, it only specifies that any value of the underlying type can be stored in the enum object, and that static_cast can be used losslessly for values in the range of the underlying type.

There is a language lawyer question here about whether sizeof(ECode) == sizeof(char) must hold, although the answers seem to say "the standard doesn't actually say so but they probably meant it".

But even if the size is the same there isn't a representation guarantee, eg the bits could be stored in some different order and the static_cast transforms the bits.

In [basic.fundamental] where it specifies the representation of integer types, it even has an explicit footnote saying that enumerations are not integer types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM