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.
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 .
Gibt es Gründe, Bitfield-Strukturen zu vermeiden?
bitfield-Strukturen haben einige Einschränkungen:
scanf()
) und das Verwenden von Zeigern auf Bitfeldern ist aufgrund der Nichtadressierbarkeit nicht möglich.sizeof()
-Operator kann nicht auf die Bitfelder angewendet werden, da sizeof()
das Ergebnis in Bytes und nicht in Bits liefert.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?
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
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 .