2013-01-07 9 views
7
#include <stdint.h> 
#include <stdio.h> 

typedef union { 
    uint64_t u[2]; 
    struct { 
     uint64_t a:30; 
     uint64_t b:30; 
     uint64_t c:30; 
     uint64_t d:30; 
     uint64_t e:8; 
    }x; 
} mystruct; 

int main() 
{ 
    printf("Size %d\n", sizeof(mystruct)); 
} 

Ich versuche, es auf 64-Bit-Maschine zu kompilieren. Die erwartete Ausgabe war 16, aber ich bekomme 24. Ich weiß, einige Ausrichtung passiert hier, aber ich bin mir nicht sicher, warum, wie die Struktur x genau 16 Bytes ist. Kann jemand das erklären. Danksizeof zeigt nicht die erwartete Ausgabe

+2

Sie Bitfelder verwenden: K & R Seite 150: *“ Fast alles über Bitfelder ist implementierungsabhängig "*. Persönlich hätte ich das "Fast" weggelassen. – cdarke

+2

@cdark sie sagen * fast * weil der Rest ist nicht spezifiziert;) – ouah

Antwort

6

Von dem C Standard:

(C99, 6.7.2.1p10) „[...] Wenn nicht genügend Raum bleibt, , ob ein Bit-Feld, das nicht paßt in denen setzte nächste Einheit oder überlappt benachbarte Einheiten ist Implementierung definiert. "

So in Ihrer Implementierung sie sich nicht überlappen: a und b Mitglieder in einer Einheit sind, c und d in einer anderen Einheit und e ist in einer anderen Einheit: 8 + 8 + 8 = 24.

6

Für eine 64-Bit-Maschine, Felder a und b Verwendung 60 Bits des ersten 64-Bit-Wertes in der struct, c und d Verwendung 60 Bits des nächsten 64-Bit-Wertes in dem struct, und dann, weil e ist 8 Bits, es kann nicht in die 4 Bits passen, die von diesem 64-Bit-Wert übrig sind, so dass ein weiterer 64-Bit-Wert benötigt wird. Also 8x3 = 24 Bytes.

3

Ein Element eines Bitfeldes wird niemals zwei Speichereinheiten "überlappen" (in Ihrem Fall ist die Speichereinheit ein 64-Bit-Element).

Neben der Tatsache, dass bitfield Implementierung sind Compiler abhängig, gibt es alle Chancen, dass Ihre bitfield Struktur tatsächlich die folgende Art und Weise in einem Speicher gespeichert wird:

struct { 
    uint64_t a:30; 
    uint64_t b:30; 
    uint64_t :4; 
    uint64_t c:30; 
    uint64_t d:30; 
    uint64_t :4; 
    uint64_t e:8; 
    uint64_t :56; 
}x;