Why is the size of an enum
always 2 or 4 bytes (on a 16- or 32-bit architecture respectively), regardless of the number of enumerators in the type?
Does the compiler treat an enum
like it does a union
?
In both C and C++, the size of an enum
type is implementation-defined, and is the same as the size of some integer type.
A common approach is to make all enum
types the same size as int
, simply because that's typically the type that makes for the most efficient access. Making it a single byte, for example, would save a very minor amount of space, but could require bigger and slower code to access it, depending on the CPU architecture.
In C, enumeration constants are by definition of type int
. So given:
enum foo { zero, one, two };
enum foo obj;
the expression zero
is of type int
, but obj
is of type enum foo
, which may or may not have the same size as int
. Given that the constants are of type int
, it tends to be easier to make the enumerated type the same size.
In C++, the rules are different; the constants are of the enumerated type. But again, it often makes the most sense for each enum
type to be one "word", which is typically the size of int
, for efficiency reasons.
And the 2011 ISO C++ standard added the ability to specify the underlying integer type for an enum
type. For example, you can now write:
enum foo: unsigned char { zero, one, two };
which guarantees that both the type foo
and the constants zero
, one
, and two
have a size of 1 byte. C does not have this feature, and it's not supported by older pre-2011 C++ compilers (unless they provide it as a language extension).
(Digression follows.)
So what if you have an enumeration constant too big to fit in an int
? You don't need 231, or even 215, distinct constants to do this:
#include <limits.h>
enum huge { big = INT_MAX, bigger };
The value of big
is INT_MAX
, which is typically 231-1, but can be as small as 215-1 (32767). The value of bigger
is implicitly big + 1
.
In C++, this is ok; the compiler will simply choose an underlying type for huge
that's big enough to hold the value INT_MAX + 1
. (Assuming there is such a type; if int
is 64 bits and there's no integer type bigger than that, that won't be possible.)
In C, since enumeration constants are of type int
, the above is invalid. It violates the constraint stated in N1570 6.7.2.2p2:
The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
and so a compiler must reject it, or at least warn about it. gcc, for example, says:
error: overflow in enumeration values
An enum is not a structure, it's just a way of giving names to a set of integers. The size of a variable with this type is just the size of the underlying integer type. This will be a type needed to hold the largest value in the enum. So as long as all the types fit in the same integer type, the size won't change.
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