Question
When a struct member is a struct, its alignment and size are different from native types?
I found an interesting phenomenon when programming in C: when a member of a structure is a structure, the alignment requirement of this structure member is the size of its largest member. I didn't find relevant content in the C standard (if I am blind, please remind me), but mainstream compilers all implement it this way.
Let's look at the following code:
#include <stdio.h>
#include <stdint.h>
struct W {
uint8_t hi;
uint8_t lo;
};
struct S1 {
uint8_t b1;
uint16_t w1;
};
struct S2 {
uint8_t b1;
struct W w1;
};
int main(int argc, const char* argv[])
{
printf("sizeof(uint16_t) : %zu\n", sizeof(uint16_t));
printf("sizeof(struct W) : %zu\n", sizeof(struct W));
printf("sizeof(struct S1): %zu\n", sizeof(struct S1));
printf("sizeof(struct S2): %zu\n", sizeof(struct S2));
printf("================================================\n");
struct S1 s1 = { 0 };
printf("&s1 : %p\n", &s1);
printf("&s1.b1 : %p\n", &s1.b1);
printf("&s1.w1 : %p\n", &s1.w1);
struct S2 s2 = { 0 };
printf("&s2 : %p\n", &s2);
printf("&s2.b1 : %p\n", &s2.b1);
printf("&s2.w1 : %p\n", &s2.w1);
printf("&s2.w1.hi: %p\n", &s2.w1.hi);
printf("&s2.w1.lo: %p\n", &s2.w1.lo);
}
The output is as follows:
sizeof(uint16_t) : 2
sizeof(struct W) : 2
sizeof(struct S1): 4
sizeof(struct S2): 3
================================================
&s1 : 0000003D4C97FCB4
&s1.b1 : 0000003D4C97FCB4
&s1.w1 : 0000003D4C97FCB6
&s2 : 0000003D4C97FCD4
&s2.b1 : 0000003D4C97FCD4
&s2.w1 : 0000003D4C97FCD5
&s2.w1.hi: 0000003D4C97FCD5
&s2.w1.lo: 0000003D4C97FCD6
When the size of member w1
is 2 bytes, why is sizeof(struct S2)
smaller than sizeof(struct S1)
? And struct S1
is 2-byte aligned but struct S2
is 1-byte aligned.
This code has been run on both MSVC and GCC with consistent results.