C
CBFalconer
Kevin said:Section 6.3.1.1p2:
"The following may be used in an expression wherever an int or
unsigned int may be used:
- An object or expression with an integer type whose integer
conversion rank is less than the rank of int and unsigned int.
- A bit-field of type _Bool, int, signed int or unsigned int.
If an int can represent all values of the original type, the value
is converted to an int; otherwise it is converted to an unsigned
int. These are called the integer promotions."
The ambiguity arises from what the "original type" is, and hence
what "all values" are. In the case of the 4-bit unsigned bitfield,
is it of type unsigned int, so all values are 0..UINT_MAX, or are
all values 0..15?
I'd always understood it to be the latter interpretation, so it
promotes to int. A look check at our compiler agrees with this -
it promotes to int, unless in pcc compatibility mode where it
promotes to unsigned int.
This may be supported by 6.7.2.1p9 which states:
"A bit-field is interpreted as a signed or unsigned integer type
consisting of the specified number of bits."
That at least gives wording strong enough to allow the bit-field to
have a distinct type with range 0..15 for the purposes of 6.3.1.1p2.
Maybe the way to attack it is by how any sane code generator
designer would go about it. The first thing to do is to get the
memory block holding the thing in question into a register. The
next is to shift that register so that the field in question is
right justified. Now the question arises of what to do with the
unspecified bits. They may either be masked off to 0 (i.e. the
field was unsigned) or jammed to copies of the left hand bit of the
original field (i.e. the field was signed, assuming 2's
complement). For 1's complement things are the same here, and for
sign-magnitude different (closer to unsigned treatment, but move
the sign bit over to its proper place).
After that we have an entity in a register, which is assumedly the
most convenient size that is normally used for ints, signed or
unsigned, and we can proceed from there. It seems to me that most
designers would opt for the unsigned version, because it is simpler
to process, and they are allowed to.
That means that the signed/unsigned characteristic of the bit field
is propagated into any expressions using it.
It also means that wherever given the choice, the designer will
make a bit field unsigned because it means less processing and less
chance of overflows and consequent UB.