Why is std::byte an enum class instead of a class?
Asked Answered
C

2

33

std::byte is an abstraction that is supposed to provide a type safe(r) access to regions of memory in C++, starting with the new standard 17. However, it's declared this way according to http://en.cppreference.com/w/cpp/types/byte:

enum class byte : unsigned char {} ;

That is, it is an enum class without any enumerations. Since usually the purpose of enums is to provide a restricted set of enumerations, this seems a bit strange. A class with a private unsigned char member seems like the more obvious way to do this.

Why is it done this way?

Churr answered 12/6, 2017 at 20:27 Comment(0)
V
34

A class with an unsigned char member would not be required by the standard to be the same size or alignment as unsigned char. Whereas the standard requires that enumerations be the same size and alignment as their underlying types.

Now, the standard could have simply declared that it is a class type with no standard-defined member, but with specific requirements on its size, alignment, constexpr constructors, etc; implementations would have to follow through on those expectations. But it's much easier to simply use enum class to get the same effect. You get all of the constructors and conversion behavior that you'd expect. And since enum class types are treated as different types than their underlying type, you get all of the behavior you want with no real downside to defining it this way.

Vasily answered 12/6, 2017 at 20:33 Comment(0)
J
4

As already mentioned by the accepted answer, the goal is for std::byte to have the same size, alignment, and representation as unsigned char. Implementations have too much freedom when it comes to classes. For example, implementations are not prevented from over-aligning struct byte { unsigned char b; };, although none over-align in practice.

You can find more rationale in the proposal for std::byte, P0298 - A byte type definition:

Implementation Alternatives

Two possible definitions of std::byte were originally considered:

// Alternative A:
namespace std {
    enum class byte : unsigned char {};
}

and

// Alternatve B:
namespace std {
    using byte = /* implementation defined */;
}

We find alternative A easier to present and explain to ordinary programmers. For all practical purposes, it has the right semantics. After presenting both alternatives to the Library Working Group, straw polling showed unanimous support for the Alternative A, which is the form presented in this paper.

Johen answered 28/8, 2023 at 12:59 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.