Question

Every book I searched, every tutorial on the internet and every q&a on SO says, that bitfields have to be integer type. Why is that?

Was it helpful?

Solution

Let's ask the converse question:

  • What types other than an integer type could a bit field be?

Let's review the options:

  1. void: not a value — wouldn't work.
  2. Pointers: but pointers on a machine are fixed size; you can't use 13 bits of a pointer and expect it to mean anything.
  3. Structures, unions: but then you aren't dealing with simple fields.
  4. That leaves float or double, but those are carefully designed formats and you can't simply use 13 bits out of a double (or float) and expect it to mean anything.

So, after you've gone through the options, you are left with the various types of integer: char, short, int, long, long long (in signed and unsigned forms), and _Bool. Of these options, the standard specifies that you can use _Bool, unsigned int, signed int and 'plain' int:

ISO/IEC 9899:2011 §6.7.2.1 Structure and union type specifiers

¶5 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. It is implementation-defined whether atomic types are permitted.

The behaviour of 'plain' int is implementation defined: it may be signed or unsigned (roughly like 'plain' char can be signed or unsigned). So, the comment by jxh is correct; I was careless quoting too many types (but I've rephrased things so that it isn't so misleading).

Note that most of the behaviour of bit-fields is implementation defined; beyond the notation, there is very little that is specified by the standard.

OTHER TIPS

Integers are a simple set of weighted bits. They are quiet, unassuming, and lend themselves readily to bit manipulation.

Almost every other data type is subject to some sort of interpretation: floating point numbers have two parts, a mantissa and an exponent; strings are ... well, strings of bytes (or Unicode values). A structure, or a pointer to an array, can represent almost anything.

As an example, I can easily store 32 bits in an integer, and retrieve them like so (c-like pseudocode):

int GetBit(int field, int position)
{
    return field & 1 << position;
}

Where the return value is either 1 or 0, stored in an integer.

A byte (eight bits) is sort of the lowest common denominator in a computer system; computers won't let you retrieve quantities of bits smaller than that directly, and most computers nowadays retrieve bits in multi-byte quantities. A 32 bit computer retrieves... well, 32 bits at a time; a 32 bit integer, which is where our conversation began.

It is just how bit-fields are defined to be, they can only take on (certain) integer types and are interpreted as integer values.

C.11 §6.7.2.1 ¶5:

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. It is implementation-defined whether atomic types are permitted.

C.11 §6.7.2.1 ¶10:

A bit-field is interpreted as having a signed or unsigned integer type consisting of the specified number of bits. If the value 0 or 1 is stored into a nonzero-width bit-field of type _Bool, the value of the bit-field shall compare equal to the value stored; a _Bool bit-field has the semantics of a _Bool.

If you are wondering about how a bit-field is used, bit-fields are typically used to create a smaller type than what it is based on. And, as the name implies, it is expected the "variables" of that type be useful for bit-manipulation. And bit operations are traditionally, and intuitively, performed with integer types.

Virtually all other types (i.e. non-integers) exist in the language mostly because they are (or can be) directly supported by the underlying hardware. That applies, for example, to pointer types and floating-point arithmetic types. The underlying hardware immediately imposes strict format and bit-size requirements on the object representation of the type. It is not possible to change the bit-size of the type and still keep it directly supported by the hardware.

In order to implement such feature as bit-fields for non-integer types the implementation would have to provide software-level support for bit-field versions of those types, i.e. it would have to emulate support for such types. This would be rather complicated and inefficient, so the language standard does not include this as a feature. Meanwhile, for integer types this is not difficult to implement with great efficiency.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top