Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constant enum size no matter the number of enumerated values

Tags:

c++

c

enums

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?

like image 431
anand Avatar asked Jul 26 '13 18:07

anand


2 Answers

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

like image 167
Keith Thompson Avatar answered Oct 22 '22 17:10

Keith Thompson


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.

like image 20
Barmar Avatar answered Oct 22 '22 16:10

Barmar