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) |
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 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: }
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