Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can sizeof(enum) differ from sizeof(std::underlying_type<Enum>::type)?

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?

like image 408
Fantastic Mr Fox Avatar asked Dec 03 '19 12:12

Fantastic Mr Fox


People also ask

How do you specify the size of an enum?

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.

How do you determine the size of an enum in a byte?

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) .

Why is sizeof enum 4?

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.


1 Answers

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 of sizeof() 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.

like image 66
StoryTeller - Unslander Monica Avatar answered Oct 08 '22 06:10

StoryTeller - Unslander Monica