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