Namespaces
Variants

Bit-fields

From cppreference.net

Deklariert ein Mitglied mit expliziter Breite in Bits. Benachbarte Bitfeld-Mitglieder können gepackt werden, um einzelne Bytes zu teilen und zu überbrücken.

Eine Bitfeld-Deklaration ist eine struct - oder union -Mitglieddeklaration, die den folgenden Deklarator verwendet:

Bezeichner  (optional) : Breite
identifier - ein Name des deklarierten Bitfelds. Der Name ist optional: namenlose Bitfelder führen die angegebene Anzahl von Bits als Auffüllung ein
width - ein ganzzahliger konstanter Ausdruck mit einem Wert größer oder gleich null und kleiner oder gleich der Anzahl der Bits im zugrundeliegenden Typ. Wenn größer als null, ist dies die Anzahl der Bits, die dieses Bitfeld belegen wird. Der Wert null ist nur für namenlose Bitfelder erlaubt und hat eine spezielle Bedeutung: er gibt an, dass das nächste Bitfeld in der Klassendefinition an der Grenze einer Zuordnungseinheit beginnt.

Inhaltsverzeichnis

Erklärung

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

  • unsigned int , für vorzeichenlose Bitfelder (z.B. unsigned int b : 3 ; hat den Wertebereich [ 0 , 7 ] )
  • signed int , für vorzeichenbehaftete Bitfelder ( signed int b : 3 ; hat den Wertebereich [ - 4 , 3 ] )
  • int , für Bitfelder mit implementierungsabhängiger Vorzeichenbehaftung (beachten Sie, dass sich dies von der Bedeutung des Schlüsselworts int an allen anderen Stellen unterscheidet, wo es "signed int" bedeutet). Zum Beispiel kann int b : 3 ; den Wertebereich [ 0 , 7 ] oder [ - 4 , 3 ] haben.
  • _Bool , für Ein-Bit-Bitfelder (z.B. bool x : 1 ; ) hat den Wertebereich [ 0 , 1 ] und implizite Konvertierungen zu und von diesem folgen den booleschen Konvertierungsregeln.
(seit C99)
  • Bit-genaue Ganzzahltypen (z.B. _BitInt ( 5 ) : 4 ; hat den Wertebereich [ - 8 , 7 ] und unsigned _BitInt ( 5 ) : 4 ; hat den Wertebereich [ 0 , 15 ] ).
(seit C23)

Zusätzliche implementierungsdefinierte Typen können zulässig sein. Es ist ebenfalls implementierungsdefiniert, ob ein Bitfeld einen atomic Typ haben darf. (since C11) Die Anzahl der Bits in einem Bitfeld ( width ) legt die Grenze des Wertebereichs fest, den es halten kann:

#include <stdio.h>
struct S
{
    // Drei-Bit-Feld ohne Vorzeichen,
    // erlaubte Werte sind 0...7
    unsigned int b : 3;
};
int main(void)
{
    struct S s = {7};
    ++s.b; // Vorzeichenloser Überlauf
    printf("%d\n", s.b); // Ausgabe: 0
}

Mehrere benachbarte Bitfelder dürfen (und werden normalerweise) zusammengepackt werden:

#include <stdio.h>
struct S
{
    // wird normalerweise 4 Bytes belegen:
    // 5 Bits: Wert von b1
    // 11 Bits: ungenutzt
    // 6 Bits: Wert von b2
    // 2 Bits: Wert von b3
    // 8 Bits: ungenutzt
    unsigned b1 : 5, : 11, b2 : 6, b3 : 2;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // gibt normalerweise 4 aus
}

Das spezielle unnamed bit-field mit width Null unterbricht das Padding: Es legt fest, dass das nächste Bit-Feld am Anfang der nächsten Zuweisungseinheit beginnt:

#include <stdio.h>
struct S
{
    // belegt normalerweise 8 Bytes:
    // 5 Bits: Wert von b1
    // 27 Bits: ungenutzt
    // 6 Bits: Wert von b2
    // 15 Bits: Wert von b3
    // 11 Bits: ungenutzt
    unsigned b1 : 5;
    unsigned    : 0; // startet ein neues unsigned int
    unsigned b2 : 6;
    unsigned b3 : 15;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // gibt normalerweise 8 aus
}

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

Hinweise

Die folgenden Verwendungen von Bitfeldern verursachen undefiniertes Verhalten :

Die folgenden Eigenschaften von Bitfeldern sind nicht spezifiziert :

  • Ausrichtung der Zuweisungseinheit, die ein Bitfeld enthält.

Die folgenden Eigenschaften von Bitfeldern sind implementierungsdefiniert :

  • Ob Bitfelder vom Typ int als vorzeichenbehaftet oder vorzeichenlos behandelt werden.
  • Ob andere Typen als int , signed int , unsigned int , _Bool (seit C99) , und (möglicherweise unsigned ) _BitInt ( N ) (seit C23) erlaubt sind.
  • Ob atomare Typen erlaubt sind.
(since C11)
  • Ob ein Bitfeld eine Grenze einer Zuordnungseinheit überschreiten kann.
  • Die Reihenfolge von Bitfeldern innerhalb einer Zuordnungseinheit (auf einigen Plattformen werden Bitfelder von links nach rechts gepackt, auf anderen von rechts nach links).

Obwohl die Anzahl der Bits in der Objektdarstellung von _Bool mindestens CHAR_BIT beträgt, darf die Breite des Bitfelds vom Typ _Bool nicht größer als 1 sein.

(seit C99)

In der C++-Programmiersprache kann die Breite eines Bitfelds die Breite des zugrundeliegenden Typs überschreiten (die zusätzlichen Bits sind jedoch Padding-Bits), und Bitfelder vom Typ int sind immer vorzeichenbehaftet.

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 Unionspezifizierer

Siehe auch

C++ Dokumentation für Bit-field