You should never use plain
int as the bitfield type if you’re expecting something about the value besides that it can hold
n bits – according to the C11 standard it is actually implementation-defined whether
int in a bit-field is signed or unsigned 6.7.2p5:
5 Each of the comma-separated multisets designates the same type, except that for bit-fields, it is implementation-defined whether the specifier
intdesignates the same type as
signed intor the same type as
In your case the
int designates the same type as
signed int; this is the default in GCC:
Whether a “plain” int bit-field is treated as a signed int bit-field or as an unsigned int bit-field (C90 6.5.2, C90 188.8.131.52, C99 and C11 6.7.2, C99 and C11 184.108.40.206).
By default it is treated as
signed intbut this may be changed by the
Thus any sane program always specifies either
signed int or
unsigned int, depending on which is appropriate for the current use case.
Then it is implementation defined whether the signed numbers are in one’s complement, or two’s complement – or perhaps sign and magnitude – if they’re in one’s complement or s-and-m, then the only value that can be stored in 1 bit is the sign bit, thus 0; so signed bit field of one bit probably makes sense only with 2’s complement.
Your system seems to use 2’s complement – this is e.g. what GCC always uses:
Whether signed integer types are represented using sign and magnitude, two’s complement, or one’s complement, and whether the extraordinary value is a trap representation or an ordinary value (C99 and C11 220.127.116.11).
GCC supports only two’s complement integer types, and all bit patterns are ordinary values.
and thus the bit values
0 are interpreted in terms of signed two’s complement numbers: the former has sign bit set, so it is negative (
-1) and the latter doesn’t have a sign bit set so it is non-negative (
Thus for a signed bit-field of 2 bits, the possible bit patterns and their integer values on a 2’s complement machine are
In an n-bit-field, the minimum signed number is – 2^(n – 1) and the maximum is 2^(n-1) – 1.
Now, when arithmetic is performed on a signed integer operand whose rank is less than
int, it is converted to an
int first, and thus the value
-1 is sign-extended to full-width
int; the same happens for default argument promotions; the value is sign-extended to a (full-width)
int when it is passed in to
Thus if you expect a sensible value from one bit bitfield, use either
unsigned bit: 1; or alternatively if this is to be understood as a boolean flag,
_Bool bit: 1;