Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++, does the size of an enumeration have to be equal to the size of its underlying type?

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:

  1. Is there any relation between an enum's underlying type and its object representation?

  2. Does the standard really require that sizeof(std::underlying_type_t<E>) == sizeof(E) for any enumeration E?

like image 442
Jan Tušil Avatar asked Nov 22 '17 21:11

Jan Tušil


People also ask

What is the size of enumeration in C?

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.

Can enum values be compared in C?

How to compare Enum values in C#? Enum. CompareTo(Object) Method is used to compare the current instance to a specified object and returns an indication of their relative values.

How do you define the size of an enum?

The size of an enum is compiler-specific and should default to the smallest integral type which is large enough to fit all of the values, but not larger than int. In this case, it seems the sizeof enum is fixed at 16-bit.

How is an enumeration defined in C?

Enumeration or Enum in C is a special kind of data type defined by the user. It consists of constant integrals or integers that are given names by a user. The use of enum in C to name the integer values makes the entire program easy to learn, understand, and maintain by the same or even different programmer.


2 Answers

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.

like image 61
OriBS Avatar answered Sep 28 '22 02:09

OriBS


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:

  1. the representation must be the same

  2. size must be equal

(But I do think that underlying type should be defined better in the standard)

like image 24
geza Avatar answered Sep 28 '22 04:09

geza