Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sizeof enums

1 view
Skip to first unread message

John Fisher

unread,
Oct 18, 2000, 11:34:57 PM10/18/00
to
A number of compiler vendors whose compilers I have used and are familiar
with seem to believe that the size of an enum type must be the same as
sizeof int for conformance to the C standards. However C90 6.5.2.2 and C99
6.7.2.2 (or at the least the draft I have) say:

"Each enumerated type shall be compatible with an integer type; the choice
of type is implementation defined"

So with the following definitions and a typical machine there is nothing
stopping a compiler from making sizeof (small_enum) == 1,
sizeof(medium_enum) == 2 and sizeof(large_enum) == 4 is there?

typedef {a, b, c} small_enum;
typedef {d = 0, e = 10000, f = -10000} medium_enum;
typedef {g = 10000000,h = 0, i = -10000000} large_enum;

I am aware that both standards specify that the enumeration constants are
ints, but I believe that nowhere do they say that the types are the same as
int, is this correct?

I recognize that many compilers can be configured so that the compiler
chooses the smallest available size that can contain the enumeration
constants, but compiler documentation often implies that to conform to the C
standards they must be configured so that sizeof any enum is sizeof int.

If I am right and this is a misunderstanding on the part of these vendors,
why is it so common?

James Kuyper

unread,
Oct 19, 2000, 1:18:38 AM10/19/00
to
John Fisher wrote:
>
> A number of compiler vendors whose compilers I have used and are familiar
> with seem to believe that the size of an enum type must be the same as
> sizeof int for conformance to the C standards. However C90 6.5.2.2 and C99
> 6.7.2.2 (or at the least the draft I have) say:
>
> "Each enumerated type shall be compatible with an integer type; the choice
> of type is implementation defined"

Yes, and in particular, "char" is mentioned as one of the possibilities,
which rules out the claim I've seen made that integer types larger than
'int' are legal, but not ones that are smaller.

Clive D.W. Feather

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
In article <9719265...@busy.neca.nec.com.au>, John Fisher
<jfi...@tns.neca.nec.com.au> writes

>So with the following definitions and a typical machine there is nothing
>stopping a compiler from making sizeof (small_enum) == 1,
>sizeof(medium_enum) == 2 and sizeof(large_enum) == 4 is there?

Correct.

>typedef {a, b, c} small_enum;
>typedef {d = 0, e = 10000, f = -10000} medium_enum;
>typedef {g = 10000000,h = 0, i = -10000000} large_enum;

You mean "typedef enum" in each case.

>I am aware that both standards specify that the enumeration constants are
>ints, but I believe that nowhere do they say that the types are the same as
>int, is this correct?

In C99 we made it clear that the type that the enumerated type is
compatible with must be able to hold all the enumerated constants. Apart
from that, you're right.

--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 20 8371 1138 | Demon Internet | Home: <cl...@davros.org>
Fax: +44 20 8371 1037 | Thus plc | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address

David R Tribble

unread,
Oct 25, 2000, 3:00:00 AM10/25/00
to
John Fisher wrote:
> A number of compiler vendors whose compilers I have used and are
> familiar with seem to believe that the size of an enum type must be
> the same as sizeof int for conformance to the C standards. However C90
> 6.5.2.2 and C99 6.7.2.2 (or at the least the draft I have) say:
>
> "Each enumerated type shall be compatible with an integer type; the
> choice of type is implementation defined" [...]

The rules state that sizeof(enum E) can be the same as sizeof(I),
where E is any given enum type and I is an integer type.

The rules also state that sizeof(RED), where RED is an enumeration
constant, is exactly the same as sizeof(int).

In other words, enum *types* can be any integer type (and width)
underneath, but enum *constants* must be ints.

Because of the first rule, a compiler is free to use 'signed char'
for a given enum type, provided that all of that type's values
(including zero) will fit into a signed char.

Because of the second rule, any compiler that supports enum types
wider than int (and, thus, enum constants wider than int) is going
beyond the ISO requirements.

--
David R. Tribble, mailto:da...@tribble.com, http://david.tribble.com

John Fisher

unread,
Oct 27, 2000, 12:54:31 AM10/27/00
to
Thank you all for confirming my understanding.

I am still a little curious why so many vendors configure their compilers to
enum-is-int by default rather than enum-is-smallest (including gcc). My best
guess is that it makes data structures more likely to end up the same size
on different architectures and slightly more portable.

This is a problem for some of the software development I do as a third party
library we use must be compiled using enum-is-int and therefore so must our
code, but we have data structures where we can't afford to waste the space,
so we have a choice between not using enums or using a packed enum language
extension, which many but not all compilers provide.

If enum-is-smallest rather than enum-is-int was the more common practice, it
is likely that the library vendor would have chosen it and we wouldn't have
had to make this unfortunate choice.

Has the committee ever given consideration to standardizing some sort of
compiler direction here for individual enums, perhaps by way of a packed
type qualifier, or creating a standard pragma?


Keith Thompson

unread,
Oct 27, 2000, 2:33:51 AM10/27/00
to

Since I'm suggest a workaround rather than discussing standards
issues, I'm cross-posting this comp.lang.c and directing followups
there.

Since C enum literals are of type int, your objects (struct members?)
don't necesssarily have to be of an enum type. For example:

enum color_literals { red, green, blue };
typedef unsigned char color;
typedef struct {
int data;
float more_data;
color c;
} foo;

The enum type declaration just creates the literals; the objects
themselves are of type unsigned char. You can do things like

foo_obj.c = green;

as easily as if color really were an enum type.

One possible drawback to this approach is that symbolic debuggers will
show the value as 1, not as the identifier "green".

It would certainly be cleaner to be able to have literals and objects
be of the same type, but C enums don't provide strong typing anyway.
(I'm not sure this would work as well in C++; if C++ compatibility is
a concern, you know where to find the C++ newsgroups.)

--
Keith Thompson (The_Other_Keith) k...@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.

John Fisher

unread,
Oct 29, 2000, 6:44:03 PM10/29/00
to
I was already aware when I posted of the work around Keith Thompson
suggests, and which definitely does have the drawback he mentions as well.
That's why I said that it is unfortunate to be unable to use enums.

However since my last post I've thought a little more about the
standardization issues along the lines I was suggesting, and I can now why
this has been left alone by the committee.


Clive D.W. Feather

unread,
Nov 3, 2000, 3:24:43 AM11/3/00
to
In article <39F709F2...@tribble.com>, David R Tribble
<da...@tribble.com> writes

>Because of the second rule, any compiler that supports enum types
>wider than int (and, thus, enum constants wider than int) is going
>beyond the ISO requirements.

enum types that turn out to be wider than int doesn't imply that
enumeration constants are wider than int.

An implementation that made all enums compatible with intmax_t would be
conforming, but enumeration constants are still required to lie in the
band INT_MIN to INT_MAX.

Pekka Pessi

unread,
Nov 10, 2000, 3:00:00 AM11/10/00
to
In message <9726225...@busy.neca.nec.com.au> "John Fisher" <jfi...@tns.neca.nec.com.au> writes:
>This is a problem for some of the software development I do as a third party
>library we use must be compiled using enum-is-int and therefore so must our
>code, but we have data structures where we can't afford to waste the space,
>so we have a choice between not using enums or using a packed enum language
>extension, which many but not all compilers provide.

Why not use bit fields like

enum color { red, green, blue }
struct foo { enum bar : 3 ; }

?

Pekka


Fergus Henderson

unread,
Nov 10, 2000, 9:25:05 PM11/10/00
to
Pekka Pessi <Pekka...@nokia.com> writes:

>"John Fisher" <jfi...@tns.neca.nec.com.au> writes:
>>This is a problem for some of the software development I do as a third party
>>library we use must be compiled using enum-is-int and therefore so must our
>>code, but we have data structures where we can't afford to waste the space,
>>so we have a choice between not using enums or using a packed enum language
>>extension, which many but not all compilers provide.
>

> Why not use bit fields like
>
>enum color { red, green, blue }
>struct foo { enum bar : 3 ; }
>
> ?

Because standard C does not require implementations to support that.

From the C99 standard:

| 6.7.2.1 Structure and union specifiers
| ...
| [#4] A bit-field shall have a type that is a qualified or
| unqualified version of _Bool, signed int, unsigned int, or
| some other implementation-defined type.

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

0 new messages