Reputation: 170084
C++17 introduces the std::byte
type. A library type that can (supposedly) be used to access raw memory, but stands separate from the character types and represents a mere lump of bits.
So far so good. But the definition has me slightly worried. As given in [cstddef.syn]:
enum class byte : unsigned char {};
I have seen two answers on SO which seem to imply different things about the robustness of the above. This answer argues (without reference) that an enumeration with an underlying type has the same size and alignment requirements as said type. Intuitively this seems correct, since specifying an underlying type allows for opaque enum declarations.
However, this answer argues that the standard only guarantees that two enumerations with the same underlying type are layout compatible, and no more.
When reading [dcl.enum] I couldn't help but notice that indeed, the underlying type is only used to specify the range of the enumerators. There is no mention of size or alignment requirements.
What am I missing?
Upvotes: 32
Views: 3055
Reputation: 39818
CWG2590 fixed this oversight; it’s first published in C++23, but is of course meant to apply to all versions since “everyone knows” enum
works this way.
Upvotes: 3
Reputation: 21156
Essentially there is special wording all around the c++17 draft standard that gives std::byte
the same properties with regard to aliasing as char
and unsigned char
.
To give you an example, the the C++17 standard, [basic.lval] p8 states:
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined.
- [...]
- a
char
,unsigned char
, orstd::byte type
.
Essentially, anywhere that char
gets special treatment in the standard, the same is given to std::byte
. As far as accessing memory is concerned, it seems irrelevant that it is defined as an enum class
or what it's underlying type is.
However, enumeration types used to be under-specified until CWG 2590. Underlying type should determine size and alignment requirements of an enum, which added the wording:
An enumeration has the same size, value representation, and alignment requirements as its underlying type. Furthermore, each value of an enumeration has the same representation as the corresponding value of the underlying type.
You can assume that this defect report applies to C++17 as well.
Upvotes: 12
Reputation: 170084
(Documenting the comments made by @T.C. that ultimately answer my question)
(I will remove this if T.C. ever wishes to reformulate his own answer.)
Oddly enough, N2213 had wording that guarantees identical representation to underlying type, but that wording was removed in N2347. In fact, it even removed the C++03 wording providing for identical sizeof without any obvious replacement.
The more general question regarding enums and their underlying types is probably worth a core issue, given that CWG approved this formulation of
std::byte
and presumably thought that the size/alignment relationship exists. As a practical matter, the clear intent is forstd::byte
to take up, well, one byte; no sane implementer would do it differently.
Upvotes: 6