Bit Fields

Both C and C++ allow integer members to be stored into memory spaces smaller than the compiler would ordinarily allow. These space-saving structure members are called bit fields, and their width in bits can be explicitly declared. Bit fields are used in programs that must force a data structure to correspond to a fixed hardware representation and are unlikely to be portable.

A bit field declaration contains a type specifier followed by an optional name declarator, a colon, a constant integer expression that indicates the field width in bits, and a semicolon.

The following structure has three bit-field members: kingdom, phylum, and genus, occupying 2, 6, and 12 bits respectively.

 struct taxonomy {
         unsigned kingdom: 2;
         unsigned phylum: 4;
         unsigned genus: 12;
 };

If a series of bit fields does not add up to the size of an int, the structure is padded to the next int boundary.

The usual dot notation is used to reference structure members, for example:

    t.phylum = 7;

When you assign a value that is out of range to a bit field, the low-order bit pattern is preserved and the appropriate bits are assigned.

Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot be referenced or initialized. A zero-width bit field can cause the next field to be aligned on the next int boundary.

The MIPS processor has special instructions that extract or insert bit fields into a register:

Instruction Description Function
EXT Extract Bit Field Rt = ExtractField(Rs, pos, size)
INS Insert Bit Field Rt = InsertField(Rs, Rt, pos, size)

Examples

Example 1: decoding I-Format instructions
Example 2: decoding both I-Format and R-Format instructions
Example 3: bitfields in the PIC32 library include files.
Example 4: taxonmy structure from this page

C Source

C Source files: bitfields.zip


01: #include <stdio.h>
02: 
03: struct taxonomy {
04:         unsigned kingdom: 2;
05:         unsigned phylum: 4;
06:         unsigned genus: 12;
07: };
08: 
09: int main()
10: {
11:         struct taxonomy t = {0, 0, 21};
12:         t.kingdom = 1;
13:         t.phylum = 7;
14:         printf("sizeof(struct taxonomy): %d bytes\n",sizeof(struct taxonomy));
15:         printf("taxonomy: 0x%x\n",t);
16:         printf("kingdom: %d\n",t.kingdom);
17:         printf("phylum: %d\n",t.phylum);
18:         printf("genus: %d\n",t.genus);
19:         
20:         return 0;
21: }


Results

Compiling the program with Microsoft C and running from the console gave the following results:

sizeof(struct taxonomy): 4 bytes
taxonomy: 0x55d
kingdom: 1
phylum: 7
genus: 21

The variable t can be decoded as:

0101 | 0101 | 1101 (group by hex digits)
0001 0101 | 0111 | 01 (group by bitfield)
21 | 7 | 1 (convert to decimal)


Maintained by John Loomis, updated Fri Aug 08 19:18:55 2008