Reputation: 29
#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;
}
On compiling this program Size of struct on_off
is reported to 16
whereas Size of box_props
is reported to 4
. Can anyone explain the reason why this happens?
Upvotes: 3
Views: 140
Reputation: 145307
The sizes are different because of packing and alignment rules as outlined by Rishikesh Raje in his answer, but the behavior of your code might be undefined as you are passing a value of type size_t
for a printf
format %d
. You should either change the format for the standard one if your compiler supports it:
printf("\nSize of struct on_off = %zu\n", sizeof(struct on_off));
printf("\nSize of box_props = %zu\n", sizeof(struct box_props));
Or use a cast for better portability to environments that do not support C99 such as 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));
Upvotes: -1
Reputation: 8614
For the first structure
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
For the second structure
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
Upvotes: 4
Reputation: 5846
By default C structs and C++ classes are not packed. So the count
member is aligned to int boundary adding extra padding bits before it. (And structs are padded at the end to word boundary.)
On top of that unsigned : 0
is actually telling the compiler to align the struct at int boundary at that field. See also: Practical Use of Zero-Length Bitfields
So the sizeof(struct on_off)
will be 4 ints. If you removed unsigned : 0
it would be 3 ints.
If you want to pack it you need to use the pack
pragma or packed
/aligned
attributes. See: #pragma pack effect and
What is the meaning of "__attribute__((packed, aligned(4))) "
Upvotes: 1