2016-07-18 6 views
1

enthält, habe ich eine struct, die etwa wie folgt aussieht:Größe einer Struktur structs enthält bitfields

typedef unsigned __int16 UINT16; 
typedef unsigned __int64 UINT64; 

struct Example { 
    struct { 
     UINT64 var1 : 5; 
     UINT64 var2 : 2; 
     UINT64 var3 : 29; 
     UINT64 var4 : 23; 
     UINT64  : 5; 
    }; 
    struct { 
     UINT16 var5 : 4; 
     UINT16 var6 : 2; 
     UINT16  : 10; 
    }; 
}; 

ich sizeof(struct Example) erwartete 10 zurückzukehren, aber es kehrte 16. Ich habe keine Ahnung, warum dies geschieht, und ich würde mich über jeden Beitrag zu diesem Thema freuen.

+4

sehr verwandt: http://stackoverflow.com/questions/38335882/why-class-size-increases-when-int64-t-changes-to-int32-t – NathanOliver

+5

Wahrscheinlich Ausrichtung. Wenn Sie zwei 'Example'-Strukturen in einem Array haben, müssen sie wahrscheinlich auf einer 8-Byte-Grenze ausgerichtet sein (wegen der 'UINT64'). Um sicherzustellen, dass die zweite Struktur richtig ausgerichtet ist, muss die vorherige Struktur am Ende 6 Byte Padding haben. Daher ist die Größe 16. – Cornstalks

+1

Sie können '#pragma pack' oder' __attribute ((packed)) 'verwenden, um das Padding zu entfernen. Aber bevor Sie diese Entscheidung treffen, sollten Sie ein wenig über Strukturverpackungen recherchieren. Das heißt, suchen Sie nach '[c] pragma pack 'und' [c] __attribute packed' hier auf SO und lesen Sie einige der Q & A's über das Packen. – user3386109

Antwort

6

Dies ist auf die Ausrichtung der Felder zurückzuführen.

Die erste interne Struktur verwendet eine uint64_t als zugrunde liegenden Typ für das Bitfeld, während die zweite eine uint16_t als zugrunde liegenden Typ verwendet.

Damit die Struktur als Ganzes richtig ausgerichtet werden kann, muss sie mit dem gleichen Offset wie das größte interne Feld "Base" ausgerichtet werden, das in diesem Fall eine uint64_t ist und daher 8 Byte Ausrichtung erfordert .

Ohne eine solche Ausrichtung werden bei einem Array dieses Typs nicht alle Array-Elemente mit einem Offset von 8 Byte gestartet. Daher werden am Ende 6 Füllbytes hinzugefügt, um eine korrekte Ausrichtung sicherzustellen.