Was ist ein Bitfeld mit Nullbreite? [duplicate]

Lesezeit: 4 Minuten

Benutzer-Avatar
manav mn

Mögliches Duplikat:

Praktische Verwendung von Null-Längen-Bitfeldern

Warum haben einige Strukturen Bitfelder mit der Breite Null und warum ist dies erforderlich?

struct foo {
  int    a:3;
  int    b:2;
  int     :0; // Force alignment to next boundary.
  int    c:4;
  int    d:3;
};

int main()
{
        int i = 0xFFFF;
        struct foo *f = (struct foo *)&i;
        printf("a=%d\nb=%d\nc=%d\nd=%d\n", f->a, f->b, f->c, f->d);
        return 0;
}

Die Ausgabe des obigen Programms ist

[email protected]:~/programs/test$ ./a.out
a=-1
b=-1
c=-8
d=0

Bitte erklären Sie, warum diese Werte negativ sind und das Speicherlayout dieser Variablen innerhalb der Struktur?

  • Dies ist die Antwort von Microsoft, ich schlage vor, Sie werfen einen Blick darauf: msdn.microsoft.com/en-us/library/ewwyfdbe(v=vs.71).aspxtrotzdem ist die Ausrichtung immer vom Compiler abhängig.

    – Code-gijoe

    10. Dezember 2012 um 14:29 Uhr


  • struct {int a:3; intb:2; Ganzzahl: 0; int c:4; int d:3; }; was ein Layout von 000aaabb 0ccccddd ergibt, anstatt ohne :0; 0000aaab bccccddd Das Breitenfeld 0 sagt aus, dass die folgenden Bitfelder auf die nächste atomare Entität (char) gesetzt werden sollen. Die Reihenfolge der als Bitfelder deklarierten Daten erfolgt je nach Ihrer Architektur von niedrigen zu hohen Bits oder auf andere Weise.

    – manav mn

    11. Dezember 2012 um 6:34 Uhr


  • In meinem Experiment d erhält jedes Mal einen anderen Wert, wenn ich Linux gcc7.2 ausführe. Die Ausgabe ist jedoch unter Windows mingw 5.3 konstant. Es ist also stark vom Compiler abhängig.

    – Lewis Chan

    18. April 2019 um 9:09 Uhr

Benutzer-Avatar
Paul R

Aus dieser erste Treffer bei einer Google-Suche:

Bitfelder mit einer Länge von 0 müssen unbenannt sein. Unbenannte Bitfelder können nicht referenziert oder initialisiert werden. Ein Bitfeld mit einer Breite von null kann bewirken, dass das nächste Feld an der nächsten Containergrenze ausgerichtet wird, wo der Container die gleiche Größe wie der zugrunde liegende Typ des Bitfelds hat.

Was den zweiten Teil Ihrer Frage angeht, setzen Sie etwas der Bitfelder in Ihrer Struktur auf alle 1s, und da diese Felder signiert sind, führt dies zu einem negativen Wert für diese Felder. Sie können dies effektiver sehen, wenn Sie die gesamte Struktur auf 1s setzen und sich die Werte sowohl in vorzeichenbehafteten als auch vorzeichenlosen Darstellungen ansehen, z

int main()
{
    struct foo f;
    memset(&f, 0xff, sizeof(f));
    printf("a=%d\nb=%d\nc=%d\nd=%d\n", f.a, f.b, f.c, f.d); // print fields as signed
    printf("a=%u\nb=%u\nc=%u\nd=%u\n", f.a, f.b, f.c, f.d); // print fields as unsigned
    return 0;
}

Das Speicherlayout ist “es hängt davon ab”, und Sie können sich nicht auf ein bestimmtes Layout eines bestimmten Compilers verlassen. Tatsächlich sehen Sie möglicherweise ein anderes Layout von einem bestimmten Compiler, wenn Sie seine Einstellungen ändern. Versuchen Sie nicht zu raten, intuitiv zu sein oder sich auf das Layout zu verlassen.

Negative – alle Ihre Elemente sind ints, die vorzeichenbehaftet sind, also sind sie negativ, da Sie jedes Bit auf 1 initialisiert haben, also haben Sie Vorzeichenbits gesetzt. Wie für d – schlägt mich. Tippfehler?

  • Sie haben den Hauptteil der Frage nicht beantwortet – was ist der Zweck eines Bitfelds mit einer Breite von Null?

    – PaulR

    10. Dezember 2012 um 14:29 Uhr

Benutzer-Avatar
Dmytro Sirenko

Wie gesagt hier, fügen Bitfelder der Länge Null eine Ausrichtung zwischen Bitfeldern hinzu. Wenn wir mehrere Bitfelder in einer Reihe haben, ist ihr Layout kompakt, aber wenn wir eines von ihnen an der Byte/Wort/Dword-Grenze ausrichten wollen, müssen wir ein Bitfeld der Länge Null zwischen dieses und das vorherige setzen.

Beispiel aus obigem Link:

struct on_off {
                  unsigned light : 1;
                  unsigned toaster : 1;
                  int count;            /* 4 bytes */
                  unsigned ac : 4;     // this and
                  unsigned : 4;        // this and
                  unsigned clock : 1;  // this bitfields are next to each other
                  unsigned : 0;
                  unsigned flag : 1;   // this bitfield is at a 4 bytes boundary.
                 } kitchen ;

Benutzer-Avatar
SomeWittyBenutzername

Zahlen sind negativ, weil die Bitfelder signiert sind, dh wenn Sie a signed char variabel, seine Größe beträgt 8 Bit, die 256 verschiedene Werte aufnehmen kann. Die Hälfte der Werte ist positiv, der Rest ist negativ und 0. Das höchstwertige Bit gibt das Vorzeichen an (1 für negativ, 0 für positiv). Zu Bitfeldern der Länge Null siehe hier: Praktische Verwendung von Bitfeldern der Länge Null

1157910cookie-checkWas ist ein Bitfeld mit Nullbreite? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy