Namensräume
Varianten
Aktionen

Bitfelder

Von cppreference.com
< c‎ | Sprache

Deklariert ein Element mit expliziter Breite in Bits. Benachbarte Bit-Felder können gepackt werden, um einzelne Bytes zu teilen und zu überspannen.

Eine Bit-Feld-Deklaration ist eine struct- oder union-Mitgliedsdeklaration, die den folgenden Deklarator verwendet:

identifier (optional) : width
identifier - ein Name des deklarierten Bit-Feldes. Der Name ist optional: Namenslose Bit-Felder führen die angegebene Anzahl von Bits als Auffüllung ein.
width - ein ganzzahliger Konstantausdruck mit einem Wert größer oder gleich Null und kleiner oder gleich der Anzahl der Bits des zugrundeliegenden Typs. Wenn er größer als Null ist, ist dies die Anzahl der Bits, die dieses Bit-Feld belegen wird. Der Wert Null ist nur für namenlose Bit-Felder zulässig und hat eine besondere Bedeutung: Er gibt an, dass das nächste Bit-Feld in der Klassendefinition an der Grenze einer Allokationseinheit beginnt.

Inhalt

[bearbeiten] Erklärung

Bit-Felder können nur einen der folgenden (möglicherweise const- oder volatile-qualifizierten) Typen haben:

  • unsigned int, für vorzeichenlose Bit-Felder (z. B. unsigned int b : 3; hat den Bereich [07])
  • signed int, für vorzeichenbehaftete Bit-Felder (signed int b : 3; hat den Bereich [-43])
  • int, für Bit-Felder mit implementierungsabhängiger Vorzeichenbehaftung (beachten Sie, dass dies von der Bedeutung des Schlüsselworts int an allen anderen Stellen abweicht, wo es "signed int" bedeutet). Zum Beispiel kann int b : 3; den Wertebereich [07] oder [-43] haben.
  • _Bool, für Ein-Bit-Bit-Felder (z. B. bool x : 1;) hat den Bereich [01] und implizite Konvertierungen zu und von ihm folgen den booleschen Konvertierungsregeln.
(seit C99)
  • Bit-präzise Ganzzahltypen (z. B. _BitInt(5) : 4; hat den Bereich [-87] und unsigned _BitInt(5) : 4; hat den Bereich [015]).
(seit C23)

Zusätzliche implementierungsabhängige Typen können zulässig sein. Es ist auch implementierungsabhängig, ob ein Bit-Feld einen atomaren Typ haben darf.(seit C11) Die Anzahl der Bits in einem Bit-Feld (width) begrenzt den Wertebereich, den es halten kann.

#include <stdio.h>
 
struct S
{
    // three-bit unsigned field,
    // allowed values are 0...7
    unsigned int b : 3;
};
 
int main(void)
{
    struct S s = {7};
    ++s.b; // unsigned overflow
    printf("%d\n", s.b); // output: 0
}

Mehrere benachbarte Bit-Felder dürfen zusammengepackt werden (und werden normalerweise auch).

#include <stdio.h>
 
struct S
{
    // will usually occupy 4 bytes:
    // 5 bits: value of b1
    // 11 bits: unused
    // 6 bits: value of b2
    // 2 bits: value of b3
    // 8 bits: unused
    unsigned b1 : 5, : 11, b2 : 6, b3 : 2;
};
 
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // usually prints 4
}

Das spezielle *namenlose Bit-Feld* mit einer width von Null unterbricht die Auffüllung: Es gibt an, dass das nächste Bit-Feld am Anfang der nächsten Allokationseinheit beginnt.

#include <stdio.h>
 
struct S
{
    // will usually occupy 8 bytes:
    // 5 bits: value of b1
    // 27 bits: unused
    // 6 bits: value of b2
    // 15 bits: value of b3
    // 11 bits: unused
    unsigned b1 : 5;
    unsigned    : 0; // starts a new unsigned int
    unsigned b2 : 6;
    unsigned b3 : 15;
};
 
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // usually prints 8
}

Da Bit-Felder nicht notwendigerweise am Anfang eines Bytes beginnen, kann die Adresse eines Bit-Feldes nicht genommen werden. Zeiger auf Bit-Felder sind nicht möglich. Bit-Felder können nicht mit sizeof und _Alignas(seit C11)(bis C23)alignas(seit C23)(seit C11) verwendet werden.

[bearbeiten] Anmerkungen

Die folgenden Verwendungen von Bit-Feldern führen zu *undefiniertem Verhalten*:

  • Aufrufen von offsetof für ein Bit-Feld.

Die folgenden Eigenschaften von Bit-Feldern sind *nicht spezifiziert*:

  • Ausrichtung der Allokationseinheit, die ein Bit-Feld enthält.

Die folgenden Eigenschaften von Bit-Feldern sind *implementierungsabhängig*:

  • Ob Bit-Felder vom Typ int als vorzeichenbehaftet oder vorzeichenlos behandelt werden.
  • Ob Typen außer int, signed int, unsigned int, _Bool(seit C99), und (möglicherweise unsigned) _BitInt(N)(seit C23) zulässig sind.
  • Ob atomare Typen zulässig sind.
(seit C11)
  • Ob ein Bit-Feld eine Allokationseinheitgrenze überspannen kann.
  • Die Reihenfolge der Bit-Felder innerhalb einer Allokationseinheit (auf einigen Plattformen werden Bit-Felder von links nach rechts gepackt, auf anderen von rechts nach links).

Obwohl die Anzahl der Bits in der Objektrepräsentation von _Bool mindestens CHAR_BIT beträgt, kann die width des Bit-Feldes vom Typ _Bool nicht größer als 1 sein.

(seit C99)

In der Programmiersprache C++ kann die Breite eines Bit-Feldes die Breite des zugrundeliegenden Typs überschreiten (aber die zusätzlichen Bits sind Auffüllbits), und Bit-Felder vom Typ int sind immer vorzeichenbehaftet.

[bearbeiten] Referenzen

  • C23-Standard (ISO/IEC 9899:2024)
  • 6.7.2.1 Struktur- und Unionspezifizierer
  • C17-Standard (ISO/IEC 9899:2018)
  • 6.7.2.1 Struktur- und Unionspezifizierer
  • C11-Standard (ISO/IEC 9899:2011)
  • 6.7.2.1 Struktur- und Unionspezifizierer
  • C99-Standard (ISO/IEC 9899:1999)
  • 6.7.2.1 Struktur- und Unionspezifizierer
  • C89/C90-Standard (ISO/IEC 9899:1990)
  • 3.5.2.1 Struktur- und Unionsspezifizierer

[bearbeiten] Siehe auch

C++-Dokumentation für Bit-Feld