C位域结构尺寸

时间:2016-05-05 04:41:51

标签: c

#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。任何人都可以解释为什么会发生这种情况吗?

3 个答案:

答案 0 :(得分:4)

对于第一个结构

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 :(得分:1)

默认情况下,C结构和C ++类不会被打包。因此count成员与int边界对齐,在它之前添加额外的填充位。 (并且结构在末尾填充到单词边界。)

最重要的是unsigned : 0实际上告诉编译器在该字段的int边界处对齐struct。另见:Practical Use of Zero-Length Bitfields

所以sizeof(struct on_off)将是4个整数。如果您删除unsigned : 0,则为3个整数。

如果要打包,则需要使用pack pragma或packed / aligned属性。请参阅:#pragma pack effectWhat is the meaning of "__attribute__((packed, aligned(4))) "

答案 2 :(得分:-1)

由于Rishikesh Raje在其答案中概述的打包和对齐规则,因此大小不同,但是代码的行为可能未定义,因为您为{{1}传递size_t类型的值格式printf。如果您的编译器支持,您应该更改标准格式:

%d

或者使用强制转换,以便更好地移植到不支持C99的环境,例如Microsoft Visual Studio:

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