2010-11-30 15 views
10

Ich habe eine Struktur von Bitfeldern, die sich zu 48 Bits addieren. Auf GCC führt dies korrekt zu einer 6-Byte-Struktur, aber in MSVC kommt die Struktur 8 Bytes heraus. Ich muss einen Weg finden, um MSVC zu zwingen, die Struktur richtig zu packen, sowohl für die Interoperabilität als auch, weil sie in einer speicherkritischen Umgebung verwendet wird.Erzwingen von nicht ausgerichteten Bitfeldpackung in MSVC

Die folgende Struktur besteht aus drei 15-Bit-Zahlen, einer 2-Bit-Nummer und einem 1-Bit-Zeichen. 15 + 15 + 15 + 2 + 1 = 48, also sollte es theoretisch in sechs Bytes passen, oder?

struct S 
{ 
    unsigned short a:15; 
    unsigned short b:15; 
    unsigned short c:15; 
    unsigned short d:2; 
    unsigned short e:1;  
}; 

Dies ist jedoch in sizeof(S) == 8 auf beiden GCC und MSVC Ergebnisse zu kompilieren. Da ich dachte, dass dies mit der Ausrichtung zu tun haben könnte, habe ich versucht, #pragma pack(1) vor der struct-Deklaration zu verwenden und dem Compiler mitzuteilen, dass er zurück zu byte, not int, bounds geht. Auf GCC, this worked, resultierend in sizeof(S) == 6.

Allerdings, auf MSVC05, die Größe kam immer noch auf 8, auch mit pack(1) gesetzt! Nachdem ich this other SO answer gelesen habe, habe ich versucht, unsigned short d durch unsigned char und unsigned short e durch bool zu ersetzen. Das Ergebnis ist sizeof(S) == !

Ich habe festgestellt, dass, wenn ich d in zwei Ein-Bit-Felder und zwängte sie zwischen den anderen Mitgliedern, die Struktur schließlich richtig verpackt.

struct S 
{ 
    unsigned short a:15; 
    unsigned short dHi : 1; 
    unsigned short b:15; 
    unsigned short dLo : 1; 
    unsigned short c:15; 
    unsigned short e:1;  
}; 

printf("%d\n", sizeof(S)); // "6" 

Aber mit d Split so umständlich und verursacht für mich Ärger später, als ich auf der Struktur zu arbeiten. Gibt es eine Möglichkeit, MSVC zu zwingen, diese Struktur in 6 Bytes zu packen, genau wie GCC?

Antwort

5

Es ist die Implementierung definiert, wie Felder in der Struktur platziert werden. Visual Studio wird, wenn möglich, aufeinanderfolgende Bitfelder in einen zugrunde liegenden Typ einfügen und den verbleibenden Platz verschwenden. (C++ Bit Fields in VS)

+0

Danke für die Referenz - das ist gut zu wissen. – Crashworks

+0

Hervorragende Referenz! Hat mir bei meinem Problem geholfen (VC++ hat mein 16-Bit-Bitfeld immer in eine 4-Byte-Struktur verwandelt. Jetzt weiß ich warum – nirbruner

0

Ich denke nicht, und ich denke, es ist das Verhalten von MSVC, das tatsächlich korrekt ist, und GCC, die vom Standard abweichen.

AFAIK, der Standard erlaubt Bitfeldern nicht, Wortgrenzen des zugrunde liegenden Typs zu kreuzen.

+3

Von 9.6.1/„Hinweis: Bit-Felder Zuordnungseinheiten auf einigen Maschinen spreizen und nicht auf andere.“ –

3

Wenn Sie den Typ "unsigned __int64" verwenden, um alle Elemente der Struktur zu deklarieren, erhalten Sie ein Objekt mit sizeof (S) = 8, aber die letzten zwei Bytes werden nicht verwendet und die ersten sechs enthält die Daten in dem von Ihnen gewünschten Format.

Alternativ, wenn Sie eine gewisse Struktur Neuordnungs annehmen können, wird diese Arbeit

#pragma pack(1) 
struct S3 
{ 
    unsigned int a:15; 
    unsigned int b:15; 
    unsigned int d:2; 
    unsigned short c:15; 
    unsigned short e:1;  
}; 
Verwandte Themen