2016-05-05 3 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; 
} 

О составлении этой программы Размер struct on_off, как сообщается 16 тогда Размер box_props сообщается в 4. Может ли кто-нибудь объяснить причину, почему это происходит?C Битовые поля Размер структур

+0

Могут быть потому что упростить выравнивание? Кстати, вы вызывают * неопределенное поведение *, передавая данные, имеющие неправильный тип, 'printf()'. '% zu', а не'% d', следует использовать для печати 'size_t', который возвращается из оператора' sizeof'. – MikeCAT

ответ

1

По умолчанию C structs и классы C++ не упакованы. Таким образом, член count выровнен к границе int, добавляя перед этим дополнительные биты заполнения. (И структуры дополняются в конце до границы слова.)

Кроме того, unsigned : 0 на самом деле сообщает компилятору о выравнивании структуры на границе int в этом поле. См. Также: Practical Use of Zero-Length Bitfields

Таким образом, sizeof(struct on_off) будет 4 входа. Если вы удалили unsigned : 0, это было бы 3 ints.

Если вы хотите упаковать его, вам необходимо использовать атрибуты pack или packed/aligned. См: #pragma pack effect и What is the meaning of "__attribute__((packed, aligned(4))) "

3

Для первой структуры

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 

Для второй структуры

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

размеры отличаются из-за упаковки и выравнивания правил, как это изложено Ришикеш Raje в своем ответе , но поведение вашего кода может быть неопределенным, поскольку вы передаете значение типа size_t для формата printf%d. Вы должны либо изменить формат стандартного, если ваш компилятор поддерживает его:

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

Или использовать слепок для лучшей переносимости сред, которые не поддерживают C99, такие как Microsoft Visual Studio:

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

Почему downvote? – chqrlie

Смежные вопросы