Subject: Re: Bitfields and kernel
To: m. k. buelow <token@mayn.de>
From: Steven J. Dovich <dovich@lethe.tiac.net>
List: tech-kern
Date: 09/29/1999 00:06:03
m. k. buelow wrote:
> I thought enums were treated as integral types?
> If I have "enum { SOMEFLAG =3D (1<<2) };" how else could SOMEFLAG
> be interpreted but with 4?  =

> The ANSI C rationale says:
> =

> 3.1.3.3  Enumeration constants
> =

> Whereas an enumeration variable may have any integer type that correctly
> represents all its values when widened to int, an enumeration constant i=
s
> only usable as the value of an expression.  Hence its type is simply int=
.
> (See =A73.1.2.5.)  =

> =

> So the compiler always treats SOMEFLAG as (int)SOMEFLAG, or am I
> missing something?

There are two points to consider.

First, the rationale is not normative, it cannot disambiguate
the language of the standard itself. Further, it does not exist in
the ISO printing of the standard (much to my dismay).

Second, consider an enum where the values are single-bit masks for
each bit of a of an int. For a 32 bit arch, this can be encoded as
the shift count necessary to convert 0x1 into the required mask
value. that shift count requires only 5 bits and can be stored in
a char. That works if the only thing you need the enum type for is
to represent the mask values. If you want to use it to store the
collection of bitfields, then ANSI/ISO C doesn't promise the
necessary storage to make that use portable and correct. The value
SOMEFLAG from your declaration above only requires a single bit to
store it (which then in turn requires some computation to produce
the integral value when needed).

Practically, most if not all compilers will implement the behavior
you are looking for. But unless C9x updates the enum semantics,
don't bank on storing any values other than the ones strictly
enumerated.

/sjd