When I type in the following code, I get a result of 32 bytes. It supposed to be 28 bytes, though. Why do I get that result?
//size of union variable
union U {
int x[7];
double y[3];
}z;
int main(){
printf("%d",sizeof(z));
return 0;
}
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 a union variable of the type is equal to memory needed for the largest member of it, and all members share this same memory space. In above example, "char arr[8]" is the largest member. Therefore size of union test is 8 bytes.
The size of a union is sufficient to contain the largest of its data members. Each data member is allocated as if it were the sole member of a struct. That means each member share the same memory region. There is at most one member active, but you can't find out which one.
Unions, like structs, are padded to agree with the required alignment of their members.
double
is aligned on a multiple of eight on your platform, and 32 is the smallest multiple of eight that is at least 28.
As explained in another answer, padding is used to facilitate struct (and union) member alignment and is the reason for the unexpected size that you see.
To see the size you expected (i.e. without padding), you can force the code to to ignore the alignment issue by using a pragma
statement. #pragma pack
specifically is used to indicate to the compiler that the struct
/union
be packed in a specific way, by changing the addressing alignment from the default value to something else.
The following results in a size of 28:
#pragma pack(1) //Sets compiler to align on 1 byte address boundaries
//(Effectively removing all padding)
union U {
int x[7];
double y[3];
}z;
#pragma pack() //Set packing back to what it was before
int main(){
printf("%d",sizeof(z));
return 0;
}
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