webentwicklung-frage-antwort-db.com.de

Gibt es Gründe, Bitfeldstrukturelemente zu vermeiden?

Ich wusste lange, dass es in C Bitfelder gibt und benutze sie gelegentlich, um dicht gepackte Strukturen zu definieren:

typedef struct Message_s {
     unsigned int flag : 1;
     unsigned int channel : 4;
     unsigned int signal : 11;
} Message;

Wenn ich Open Source Code lese, finde ich stattdessen oft Bitmasken und Bitverschiebungsoperationen, um solche Informationen in handgerollten Bitfeldern zu speichern und abzurufen. Dies ist so häufig, dass ich glaube, dass die Autoren die Bitfeldsyntax nicht kannten. Daher frage ich mich, ob es Gründe gibt, Bitfelder über Bitmasken und eigene Verschiebungsoperationen zu verschieben, anstatt sich auf den Compiler zu verlassen, um sie zu generieren Code zum Abrufen und Setzen solcher Bitfelder.

18
wirrbel

Warum verwenden andere Programmierer anstelle von Bitfeldern handcodierte Bitmanipulationen, um mehrere Felder in ein einziges Wort zu packen?

Diese Antwort basiert auf Meinungen, da die Frage ziemlich offen ist:

  • Viele Programmierer sind sich der Verfügbarkeit von Bitfeldern nicht bewusst oder wissen nicht, ob sie portabel sind und über eine genaue Semantik verfügen. Einige misstrauen sogar der Fähigkeit des Compilers, korrekten Code zu erzeugen. Sie bevorzugen es, expliziten Code zu schreiben, den sie verstehen.

    Wie Cornstalks kommentiert, wurzelt diese Haltung in der realen Erfahrung wie in diesem Artikel erläutert .

  • Das tatsächliche Speicherlayout von Bitfield ist durch die Implementierung definiert: Wenn das Speicherlayout einer genauen Spezifikation folgen muss, sollten keine Bitfelder verwendet werden, und es sind möglicherweise manuell codierte Bitmanipulationen erforderlich.
  • Die Übergabe von vorzeichenbehafteten Werten in vorzeichenbehafteten typisierten Bitfeldern ist durch die Implementierung definiert. Wenn vorzeichenbehaftete Werte in einen Bereich von Bits gepackt werden, ist es möglicherweise zuverlässiger, die Zugriffsfunktionen per Hand zu codieren.
15
chqrlie

Gibt es Gründe, Bitfield-Strukturen zu vermeiden?

bitfield-Strukturen haben einige Einschränkungen:

  1. Bitfelder führen zu nicht portierbarem Code. Außerdem hängt die Bitfeldlänge stark von der Word-Größe ab.
  2. Das Lesen (mit scanf()) und das Verwenden von Zeigern auf Bitfeldern ist aufgrund der Nichtadressierbarkeit nicht möglich.
  3. Bitfelder werden verwendet, um mehr Variablen in einen kleineren Datenbereich zu packen, verursachen jedoch, dass der Compiler zusätzlichen Code generiert, um diese Variablen zu bearbeiten. Dies führt zu einer Zunahme sowohl der räumlichen als auch der zeitlichen Komplexität.
  4. Der sizeof()-Operator kann nicht auf die Bitfelder angewendet werden, da sizeof() das Ergebnis in Bytes und nicht in Bits liefert.

Quelle

Es hängt also davon ab, ob Sie sie verwenden sollten oder nicht. Lesen Sie mehr unter Warum ist Bit-Endianness in Bitfeldern ein Problem?


PS: Wann werden Bitfelder in C verwendet?

8
gsamaras

Dafür gibt es keinen Grund. Bitfelder sind nützlich und bequem. Sie sind in den eingebetteten Projekten allgemein üblich. Einige Architekturen (wie ARM) enthalten sogar spezielle Anweisungen zum Bearbeiten von Bitfeldern. 

Vergleichen Sie einfach den Code (und schreiben Sie den Rest der Funktion foo1) https://godbolt.org/g/72b3vY

4
P__J__

In vielen Fällen ist es nützlich, einzelne Bitgruppen innerhalb eines Wortes ansprechen zu können oder ein Wort als Einheit zu bearbeiten. Derzeit bietet der Standard Keinen praktischen und tragbaren Weg, um eine solche Funktionalität zu erreichen. Wenn Code für die Verwendung von Bitfeldern geschrieben wird und später auf mehrere Gruppen als Word zugegriffen werden muss, gibt es keine gute Möglichkeit, dies zu berücksichtigen, ohne den gesamten Code mithilfe der Bitfelder zu überarbeiten oder typbasierte Aliasing-Optimierungen mithilfe von Typ Punning zu deaktivieren. und hoffen, dass alles wie erwartet angelegt wird.

Die Verwendung von Verschiebungen und Masken ist möglicherweise unelegant, aber solange C nicht die Möglichkeit bietet, eine explizit bestimmte - Folge von Bits innerhalb eines Werts als einen anderen Wert zu behandeln, ist es oft die beste Möglichkeit, sicherzustellen, dass der Code an die Erfordernisse angepasst werden kann .

0
supercat