【问题标题】:C Bitfields Size of Structures结构体的 C 位域大小
【发布时间】:2016-08-30 18:20:09
【问题描述】:
#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。谁能解释一下为什么会这样?

【问题讨论】:

  • 可能是因为它易于对齐?顺便说一句,您通过将类型错误的数据传递给printf() 来调用未定义的行为%zu,而不是%d,应该用于打印size_t,它是从sizeof运算符返回的。

标签: c


【解决方案1】:

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

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));

【讨论】:

    【解决方案2】:

    对于第一个结构

    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
    

    【讨论】:

      【解决方案3】:

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

      除此之外,unsigned : 0 实际上是告诉编译器在该字段的 int 边界处对齐结构。另见: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))) "

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-13
        • 2012-06-23
        • 2016-11-21
        相关资源
        最近更新 更多