Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

c++ - Constant enum size no matter the number of enumerated values

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...