2016-05-05 11 views
3
#include <stdio.h> 
int main() { 
    struct on_off { 
     unsigned light  : 1; 
     unsigned toaster : 1; 
     int count;/* 4 bytes */ 
     unsigned ac   : 4; 
     unsigned   : 4; 
     unsigned clock  : 1; 
     unsigned   : 0; 
     unsigned flag  : 1; 
    } kitchen; 
    struct box_props { 
     unsigned int opaque  : 1; 
     unsigned int fill_color : 3; 
     unsigned int    : 4; 
     unsigned int show_border : 1; 
     unsigned int border_color : 3; 
     unsigned int border_style : 2; 
     unsigned int    : 2; 
    } s; 

    printf("\n\nSize of struct on_off = %d\n", sizeof(struct on_off)); 
    printf("\nSize of box_props = %d\n", sizeof(struct box_props)); 

    return 0; 
} 

Auf dieses Programm Größe von struct on_off Kompilieren wird 16 berichtet, während Größe von box_props zu 4 berichtet. Kann jemand den Grund erklären, warum dies geschieht?C Bitfelder Größe der Strukturen

+0

Vielleicht Weil es einfach ist, sich auszurichten? Übrigens haben Sie * undefiniertes Verhalten * aufgerufen, indem Sie Daten mit falschem Typ an 'printf()' übergeben. '% zu', nicht'% d', sollte für den Ausdruck 'size_t' verwendet werden, der vom' sizeof' Operator zurückgegeben wird. – MikeCAT

Antwort

1

Standardmäßig sind C-Strukturen und C++ - Klassen nicht gepackt. Das Element count ist also auf int-Grenze ausgerichtet und fügt vor diesem zusätzliche Füll-Bits hinzu. (Und Strukturen sind am Ende bis Wortgrenze aufgefüllt.)

Darüber hinaus sagt unsigned : 0 tatsächlich den Compiler, die Struktur an int Grenze in diesem Feld auszurichten. Siehe auch: Practical Use of Zero-Length Bitfields

So wird die sizeof(struct on_off) 4 ints sein. Wenn Sie unsigned : 0 entfernt haben, wären es 3 Ints.

Wenn Sie es packen möchten, müssen Sie die pack Pragma oder packed/aligned Attribute verwenden. Siehe: #pragma pack effect und What is the meaning of "__attribute__((packed, aligned(4))) "

3

Für die erste Struktur

struct on_off{ 
    unsigned light  : 1; 
    unsigned toaster : 1; // 1 byte 
           // 3 bytes - packing to align to int border 
    int count;    // 4 Bytes   
    unsigned ac   : 4; 
    unsigned ss   : 4; // 1 Byte 
    unsigned clock  : 1; // 1 byte 
    unsigned   : 0; // 2 byte -- A size of zero forces alignment to next boundary. 
    unsigned flag  : 1; // 1 byte 
           // 3 bytes -- Packing at end of struct to align to word boundary. 
} 
           // 16 bytes -- Total 

Für die zweite Struktur

struct box_props{ 
    unsigned int opaque  : 1; 
    unsigned int fill_color : 3; 
    unsigned int    : 4; // 1 byte 
    unsigned int show_border : 1; 
    unsigned int border_color : 3; // 1 byte 
    unsigned int border_style : 2; 
    unsigned int    : 2; // 1 byte 
             // 1 byte - packing at the end of structure to align to word boundary. 
} 
             // 4 bytes Total 
-1

Die Größen Regeln, weil die Verpackung und Ausrichtung verschieden sind, wie von Rishikesh Raje in seiner Antwort skizzierte , aber das Verhalten Ihres Codes ist möglicherweise nicht definiert, da Sie einen Wert vom Typ size_t für ein printf-Formatübergeben 0. Sie sollten entweder das Format für den Standard eines ändern, wenn Ihr Compiler unterstützt:

printf("\nSize of struct on_off = %zu\n", sizeof(struct on_off)); 
printf("\nSize of box_props = %zu\n", sizeof(struct box_props)); 

Oder eine Besetzung für eine bessere Portabilität Umgebungen verwenden, die nicht über C99 wie Microsoft Visual Studio unterstützen:

printf("\nSize of struct on_off = %d\n", (int)sizeof(struct on_off)); 
printf("\nSize of box_props = %d\n", (int)sizeof(struct box_props)); 
+0

Warum der Downvote? – chqrlie