Bitvelden (bit fields) in C zijn leden van een structuur die een opgegeven aantal bits innemen in plaats van de standaardgrootte van het type. Ze besparen geheugen, vooral voor het opslaan van vlaggen en compacte statussets.
Declaratie:
struct Flags { unsigned int enable : 1; unsigned int mode : 2; unsigned int code : 5; };
In dit voorbeeld neemt de structuur minimaal 8 bits in plaats van 3 * sizeof(unsigned int).
Waar toe te passen:
Beperkingen en valkuilen:
Voorbeeld:
struct Packet { unsigned char start : 1; unsigned char id : 3; unsigned char flag : 4; };
Vraag: Mag je het type char of signed int gebruiken voor bitvelden?
Antwoord: De C-standaard staat het gebruik van int, unsigned int en (volgens compileruitbreidingen) andere standaard gehele types (char, short) toe. Echter, overdraagbaarheid is alleen gegarandeerd voor int en unsigned int.
Voorbeeld van een fout:
struct Example { signed char a : 3; }; // Bij verschillende compilers/architecturen gelden verschillende regels voor het opslaan van het teken en de volgorde van de bits.
Verhaal
Bij de integratie van software op ARM en x86 bleek dat de structuur met bitvelden anders werd uitgepakt: verschillende volgorde van bits en uitlijning. Het project was ontworpen zonder deze verschillen in overweging te nemen, wat leidde tot het onvermogen om gegevens in een cross-platform omgeving te lezen.
Verhaal
In het systeem voor het besturen van motorcontrollers werd per ongeluk het type
chargebruikt in de bit fieldstructuren. Op sommige ARM-processors ging dit gepaard met onjuiste tekenextensie, wat leidde tot onjuiste verwerking van vlaggen.
Verhaal
In een netwerkprotocol werden bitvelden gebruikt voor het verpakken van berichtvlaggen; men had niet in de gaten dat de hogere niet-geinitialiseerde velden rommelig blijven. Bij de overdracht tussen apparaten ontstonden willekeurige statusfouten door verschillen in initialisatie.