Ich schreibe eine C++-Anwendung für Windows XP/Vista/7 mit Visual Studio 2008. Einige meiner Strukturen verwenden ein Bitfeld, wie im Beispiel gezeigt.
typedef struct myStruct_tag
{
BYTE myVar1;
WORD myVar2;
WORD myVar3;
union
{
struct
{
BYTE :1;
BYTE field1 :1;
BYTE field2 :1;
BYTE reserved :5;
} myBitField;
BYTE myVar4;
};
BYTE myVar5;
BYTE myVar6;
} myStruct_t;
Welches Ende des Feldes ist das höchstwertige Bit?
C99-Standard 6.7.2.1/10 (Hervorhebung von mir):
Eine Implementierung kann jede adressierbare Speichereinheit zuweisen, die groß genug ist, um ein Bitfeld zu halten. Wenn genügend Platz verbleibt, soll ein Bitfeld, das in einer Struktur unmittelbar auf ein anderes Bitfeld folgt, in benachbarte Bits derselben Einheit gepackt werden. Wenn nicht genügend Platz verbleibt, ist es implementierungsdefiniert, ob ein Bitfeld, das nicht passt, in die nächste Einheit eingefügt wird oder benachbarte Einheiten überlappt. Die Reihenfolge der Zuweisung von Bitfeldern innerhalb einer Einheit (von hoher Ordnung zu niedriger Ordnung oder von niedriger Ordnung zu hoher Ordnung) ist implementierungsdefiniert. Die Ausrichtung der adressierbaren Speichereinheit ist nicht spezifiziert.
Die Reihenfolge muss also von Ihrer Compiler-Implementierung dokumentiert werden.
Allerdings ist so viel über die Implementierung von Bitfeldern implementierungsdefiniert oder unspezifiziert, dass ihre Verwendung zum Modellieren von Hardware-, Drahtprotokoll- oder Dateiformat-Bitfeldern auf tragbare Weise den Versuch nicht wert ist.
Wenn Sie möchten, dass Ihre “Bitfelder” etwas außerhalb Ihres Programms modellieren (wie die obigen Dinge), verwenden Sie explizite Masken, setzen und löschen Sie die Bits mit den standardmäßigen bitweisen Operatoren (|
‘&,
~,
<<` usw.). Verwenden Sie Inline-Hilfsfunktionen (oder sogar Makros, wenn Sie müssen), um dies in Ihrem Code einfacher/klarer zu machen.
Die Visual Studio 2008-Compilerdokumentation gibt Folgendes an:
Die Reihenfolge der als Bitfelder deklarierten Daten ist von niedrigem zu hohem Bit
Aus „C++-Bitfelder“, MSDN C++-Sprachreferenz, Visual Studio 2008-Version
Wenn Sie fragen, welche Bits in myBitField in welchen Bits des Bytes im Speicher gespeichert werden, ist dies durch die C-Standards ausdrücklich nicht definiert. Sie müssen durch Experimentieren lernen. Es lohnt sich wahrscheinlich, wenn Sie etwas tun, bei dem dies tatsächlich wichtig ist, stattdessen einen Ansatz zu verwenden, bei dem Sie #definieren field1
als Hex-Wert (z. B. 0x40
oder 0x02
) und platzieren Sie es an der gewünschten Stelle.
Hinweis: Laut Standard ist das MSB nicht definiert. Auf Ihrer spezifischen Plattform vermute ich das
reserved
enthält das MSB, aber ich bin nicht sicher.– Billy ONeal
28. Dezember 2010 um 16:24 Uhr
@ Billy: Das sieht für mich nach einer Antwort aus.
– Ben Voigt
28. Dezember 2010 um 16:26 Uhr
Äh … Das ist eine ziemlich seltsame Frage. Sie haben nur 3 Bitfelder in Ihrer Deklaration. 2 davon sind 1-Bit-Bitfelder, dh es gibt keine Frage, “welches Ende” bei ihnen gibt, da dort nur 1 Bit vorhanden ist. Das einzige Multi-Bit-Bit-Feld namens
reserved
, was darauf hindeutet, dass es überhaupt nicht verwendet wird. Das einzige Bitfeld, auf das Sie sich beziehen können, ist also im Grunde genommenreserved
. Fragst du nachreserved
speziell? Wenn nicht, präzisieren Sie Ihre Frage.– AnT steht zu Russland
28. Dezember 2010 um 16:26 Uhr
@Ben: Wenn ich positiv wäre, welche Variable das MSB bekommen würde, wäre es eine Antwort gewesen, aber ich bin nicht sicher …
– Billy ONeal
28. Dezember 2010 um 16:27 Uhr
Dies ist wichtig, da die Struktur verwendet wird, um ein Paket für die serielle Kommunikation zu definieren. Die Bitfelder müssen auf beiden Seiten des Systems ausgerichtet werden, wobei ich leider nur über eine Seite die Kontrolle habe.
– Jim fiel
28. Dezember 2010 um 16:30 Uhr