In most cases, this is normal with an initial sequence of any length, since all known compilers will give the common members of two struct the same addition. If they had not given them the same addition, they would have had hellish time following this C standard requirement:
To simplify the use of joins, there is one special guarantee: if the union contains several structures that have a common initial sequence, and if the union object currently contains one of these structures, it is allowed to check the common initial parts of any of them.
I really canโt imagine how the compiler will deal with this if the "initial sequence" differs differently in the two struct s.
But there is one serious "but." strict overlay must be disabled for this setting to work.
Strict anti-aliasing is a rule that basically states that two pointers of incompatible types cannot refer to the same memory location. Therefore, if you draw a pointer to your larger struct pointer to a smaller one (or vice versa), get the value of the member in their initial sequence by dereferencing one of them, and then change this value through the other, and then check it again from the first pointer, it will not be changed. I.e:.
struct smaller_struct { int memb1; int memb2; } struct larger_struct { int memb1; int memb2; int additional_memb; } struct larger_struct l_struct, *p_l_struct; struct smaller_struct *p_s_struct; p_l_struct = &l_struct; p_s_struct = (struct smaller_struct *)p_l_struct; p_l_struct->memb1 = 1; printf("%d", p_l_struct->memb1); p_s_struct->memb1 = 2; printf("%d", p_l_struct->memb1);
You see that a compiler that uses optimizations using strict anti-aliasing (for example, GCC in -O3 mode) wants to make life easier for itself: it believes that two pointers of incompatible types simply cannot refer to the same memory location, therefore, they do not believe that they are doing this. Thus, when accessing p_s_struct->memb1 he will think that nothing has ever changed the value of p_s_struct->memb1 (which, as you know, will be 1 ), so it will not check the actual value of memb1 and simply output 1 .
A way around this may be to declare your pointers as pointing to volatile data (which means telling the compiler that this data can be changed from other sources without notifying it), but the standard does not guarantee that it will work.
Note that all of the above applies to struct , which are not compiled in a special way.