I have declared a union allocating 4100 bytes to variable "sample_union" and made the same union declaration as part of a structure which is allocating 4104 bytes.
union test_size_union {
struct {
uint8_t type;
union {
uint8_t count;
uint8_t list;
};
uint16_t rc;
uint16_t arr_value[2048];
};
uint64_t first_dword;
}__attribute__((packed)) sample_union ;
Placing the above union inside structure is allocating 4104 bytes.
struct test_size_struct {
union {
struct {
uint8_t type;
union {
uint8_t count;
uint8_t list;
};
uint16_t rc;
uint16_t arr_value[2048];
};
uint64_t first_dword;
};
}__attribute__((packed)) sample_struct;
Well, this is not a project requirement, but I would like to know why compiler is behaving differently for this two declaration.
gcc version: (GCC) 4.9.2, x86_64
Platform: Linux, x86_64
The alignment of your union must be the largest alignment of any of its members. This is 4. Therefore, the size of the union must be aligned to that size. It could have been 5 (as c is the largest member of the union), but because the alignment of the union as a whole is 4, the size of the union is padded to 8.
When we declare a union, memory allocated for the union is equal to memory needed for the largest member of it, and all members share this same memory space. Since u is a union, memory allocated to u will be max of float y(4 bytes) and long z(8 bytes). So, total size will be 18 bytes (10 + 8).
When you placed the union inside the struct, you didn't mark the union as packed
. The unpacked union has a little padding (four bytes) so that its size is a multiple of the size of uint64_t
.
The packed union doesn't have this padding, so it is smaller.
As a side observation, the anonymous struct inside the union is not marked packed
. That happens not to matter in this case, because everything is nicely aligned anyway - but it's something to be aware of.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With