Some of my comments here are based on those posted in reflector message 11100.
DR#315 discusses issues concerning the type of a bit-field. For C99 the conclusion for the DR was to leave most of these matters implementation-defined, with the possibility of revisiting the matter in C1x.
The fundamental question is: in the width of a bit-field part of
its type, or is the type that with which it was declared (ignoring the
width, and with the possibility that the absence of
signed
is interpreted as unsigned
)?
For C90, this was considered in DRs #015, #120 and #122. The conclusion was that bit-fields have special types with the limited numbers of bits, that unsigned bit-fields promote accordingly (015, 122) and that when values are stored in bit-fields conversions are applied according to the special type (120).
In C90, only int
, signed int
and
unsigned int
bit-fields needed to be considered (and so
bit-fields wider than int
were irrelevant). C99 adds
_Bool
bit-fields, and the possibility of other
implementation-defined types (of course, an implementation does not
need to provide such types, and any implementation burden associated
with bit-fields wider than int
falls only on those
implementations that choose to do so).
For C++, other integral and enumeration types are allowed for bit-fields; it is explicit that bit-fields do not have special types ([class.bit], "The bit-field attribute is not part of the type of the class member.").
The following are affected by the choice between having special types and no special types:
int
.
It is however accepted for both C99 (in special wording suggested in
DR#315, covering at least the case where the declared type is
unsigned int
) and C++ (special wording in [conv.prom])
that such bit-fields promote to int
when it can represent
all values of the bit-field.int
but
with a wider declared type such as long
. In C++ these
also promote to int
.unsigned:1
bit-field (fully defined in the presence of
special types) yields 0 (taking the least significant bit) rather than
1 (taking the next bit)?unsigned short
and 32-bit unsigned int
) that storing a
float
in an unsigned int:16
bit-field must
be implemented differently, and possibly less efficiently, than
storing it in an unsigned short
, because some cases would
only be defined for the bit-field and not for the direct conversion to
16 bits.int
(as raised in DR#315). This only affect
implementations choosing to have such implementation-defined bit-field
types.The C99 standard text leaves the question of special types ambiguous.
C90 6.5.2.1 says:
The expression that specifies the width of a bit-field shall be an integral constant expression that has nonnegative value that shall not exceed the number of bits in an ordinary object of compatible type. If the value is zero, the declaration shall have no declarator.
C99 6.7.2.1, before TC2 (the changes in TC2 being irrelevant) says:
The expression that specifies the width of a bit-field shall be an integer constant expression that has nonnegative value that shall not exceed the number of bits in an object of the type that is specified if the colon and expression are omitted. If the value is zero, the declaration shall have no declarator.
"of compatible type" was changed to "of the type that is specified if the colon and expression are omitted", possibly to make the readings of the C90 DRs clearer from the text of the standard.
Both C90 and C99 also say that "A bit-field is interpreted as [an integral|a signed or unsigned integer] type consisting of the specified number of bits.", both suggesting separate types.
C90 says "A bit-field shall have a type that is a qualified or
unqualified version of one of int
, unsigned
int
, or signed int
."; C99 says "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.", both
suggesting the bit-field has the underlying type instead of the new
type.