问题
I often assume that size of an enumeration is the same as the size of its underlying type. But is it mandated by the standard?
The standard (C++14, n4296) says that every enumeration has an underlying type (7.2/5). The standard also says that objects are represented as sequences of bytes, and that the size of an object is related to its representation:
3.9/4 The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T).
5.3.3/1 The sizeof operator yields the number of bytes in the object representation of its operand.
However, I was not able to find any relation between an enum's underlying type and the object representation. Is there any? If not, than I would argue that sizeof of an enumeration does not have to be sizeof of its underlying type.
So my questions are:
Is there any relation between an enum's underlying type and its object representation?
Does the standard really require that
sizeof(std::underlying_type_t<E>) == sizeof(E)
for any enumeration E?
回答1:
Taken from: What is the underlying type of a c++ enum?, An older C++ standard stated at 7.2/5:
The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration. 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 enu- merator 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 enu- meration type, an object of enumeration type, or an enumerator, is the value of sizeof() applied to the underlying type.
From draft n4606
the closest I could find is 7.2/7 + 8 which states:
7) For an enumeration whose underlying type is not fixed, the underlying type 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 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.
8) For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, for an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values in the range bmin to bmax, defined as follows: Let K be 1 for a two’s complement representation and 0 for a ones’ complement or sign-magnitude representation. bmax is the smallest value greater than or equal to max(|emin| − K, |emax|) and equal to 2M − 1, where M is a non-negative integer. bmin is zero if emin is non-negative and −(bmax + K) otherwise. The size of the smallest bit-field large enough to hold all the values of the enumeration type is max(M, 1) if bmin is zero and M + 1 otherwise. It is possible to define an enumeration that has values not defined by any of its enumerators. If the enumerator-list is empty, the values of the enumeration are as if the enumeration had a single enumerator with value 0
On the one hand it seems close enough, on the other hand, the specific demand for the sizeof()
operator was removed.
Still I think it is safe enough to state that answer for both the questions is yes.
回答2:
I've searched the standard, and this is best I could find (I know this may not be adequate):
Underlying type is defined implicitly here (3.9.1/5 of C++14):
Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.3.1). Type wchar_t shall have the same size, signedness, and alignment requirements (3.11) as one of the other integral types, called its underlying type. Types char16_t and char32_t denote distinct types with the same size, signedness, and alignment as uint_least16_t and uint_least32_t, respectively, in <cstdint>, called the underlying types.
This definition is about wchar_t
, but I think it's safe to say that that's the definition for underlying type.
(at least, that's the best definition the standard gives. Besides, the index of C++14 standard for underlying type refers to here)
That means:
the representation must be the same
size must be equal
(But I do think that underlying type should be defined better in the standard)
来源:https://stackoverflow.com/questions/47444081/in-c-does-the-size-of-an-enumeration-have-to-be-equal-to-the-size-of-its-unde