C++ Tutorial

 Bitfelder

Bitfelder werden hauptsächlich eingesetzt, wenn auf die Hardware eines Rechners zugegriffen wird. In der Vergangenheit, vor dem Gigabyte-Zeitalter, wurden Bitfelder ebenfalls dazu verwendet, Speicherplatz einzusparen, aber auf Kosten der Laufzeit.

Definition

Ein Bitfeld wird wie folgt definiert:

struct bitfieldName
{
   DTYP1 ename1: BITS1 [INIT1];
   DTYP2 ename2: BITS2 [INIT2];
   ...
   DTYPn enamen: BITSn [INTIn];
} [bvar1];

Nach dem Schlüsselwort struct folgt (optional) ein eindeutiger Name des Bitfelds bitfieldName. Anschließend werden innerhalb einer geschweiften Klammer die Elemente des Bitfeldes aufgelistet, die jeweils durch ein Semikolon abgeschlossen werden. Nach der geschweiften Klammer zu können noch Bitfeld-Variablen bvar1 definiert werden.

Jedes Element eines Bitfeldes besteht aus einem Datentyp DTYPx und einem Namen enamex. Nach dem Namen folgt ein Doppelpunkt und anschließend die Anzahl der Bits BITSx, die das jeweilige Element belegt. Als Datentypen für die Elemente sind nur Integer-Datentypen, enum und bool zulässig.

Optional kann ein Element initialisiert werden INITn, entweder per Zuweisung oder durch einen Ausdruck in einer geschweiften Klammer.

Zugriff auf Bitfeld-Elemente

Der Zugriff auf ein Bitfeld-Element erfolgt in der Art, dass zuerst der Name der Bitfeld-Variable angegeben wird, dann ein Punkt und anschließend der Name des Bitfeld-Elements.

Ein Bitfeld zur Aufnahme eines Datums könnte damit wie folgt aussehen:

#include <iostream>
#include <format>

// Bitfeld-Definition
struct Date
{
   unsigned char day : 5 = 1;          // 5 Bits fuer den Tag (1...31)
   unsigned char month : 4 {2};        // 4 Bits fuer den Monat (1...12)
   unsigned short year : 11 {2022};    // 11 Bits fuer das Jahr (...2048)
} actDate;

int main()
{
   // Bitfeld-Elemente ausgeben
   std::cout << std::format("Heute ist der {:02}.{:02}.{:4}\n",
                             static_cast<unsigned char>(actDate.day),
                             static_cast<unsigned char>(actDate.month),
                             static_cast<unsigned short>(actDate.year));
   // Tag inkrementieren
   actDate.day++;
   // Bitfeld-Elemente erneut ausgeben
   std::cout << std::format("Morgen ist der {:02}.{:02}.{:4}\n",
                             static_cast<unsigned char>(actDate.day),
                             static_cast<unsigned char>(actDate.month),
                             static_cast<unsigned short>(actDate.year));
}

Besonderheiten

Die Reihenfolge der Elemente eines Bitfeldes ist nicht standardisiert, d.h., es ist nicht definiert, wie das Bitfeld im Speicher abgebildet wird. Hier hilft nur ein Blick ins Compiler-Handbuch.

Von einem Bitfeld-Element kann kein Feld  definiert werden und es kann von einem Bitfeld-Element keine Adresse gebildet werden.