Recently came up in a code review that in the following example:
enum class A : uint8_t
{
VAL1, VAL2
};
...
std::vector<A> vOfA; // Assume this is sized and full of some stuff.
std::memcpy(wire_buffer, vOfA.data(), vOfA.size() * sizeof(A));
We should be using sizeof(std::underlying_type<A>::type)
instead of sizeof(A)
. Is it possible that these can ever differ? Does someone have a standards quote that guarantees this?
The C standard specifies that enums are integers, but it does not specify the size. Once again, that is up to the people who write the compiler. On an 8-bit processor, enums can be 16-bits wide. On a 32-bit processor they can be 32-bits wide or more or less.
In both C and C++, the size of an enumerator sizeof(enumStruc_2) is the size of any individual element in that enumeration. In C, the answer is sizeof(int) . So that's at least 2. In C++, the answer is sizeof(std::underlying_type<enumStruc_2>::type) .
The size is four bytes because the enum is stored as an int . With only 12 values, you really only need 4 bits, but 32 bit machines process 32 bit quantities more efficiently than smaller quantities.
In C++03 it was guaranteed (well, for unscoped enumerations anyway).
[dcl.enum] Enumeration declarations (emphasis mine)
6 The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration. If no integral type can represent all the enumerator values, the enumeration is ill-formed. It is implementation-defined which integral type is used as the underlying type for an enumeration except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0. The value of
sizeof()
applied to an enumeration type, an object of enumeration type, or an enumerator, is the value ofsizeof()
applied to the underlying type.
Then came n2347, the paper that was adopted for strongly typed enumerations (enum class
) and other enhancements to unscoped enumerations, and it had the sentence in bold removed. Interestingly enough, an earlier version of the proposal, n2213, had a replacement for the removed sentence. But it didn't make into the version that was adopted.
So in modern C++, there is no obligation for the sizes to be the same. Though from a practical standpoint, implementations are unlikely to have changed the behavior prescribed by C++03 for enumeration sizes.
One could deem it a defect in the standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With