If I have two structs that have the same layout for the first couple fields, say struct Athis
and struct Bthat
, can I take an instance of Athis
and then reference it using Bthat
with regards to accessing and/or modifying those initial members/fields?
Let's say I have the following 2 structs:
struct Athis {
int num;
char *str;
int *lst;
unsigned int num_lst;
// end
};
struct Bthat {
int b_num;
char *b_str;
int *b_lst;
unsigned int b_num_lst;
// more below
char *b_not_b;
bool b_hamlet;
long guildenst;
unsigned long rosencr;
};
Can I then do this, safely, all the time?
void do_stuff(struct Athis *a) {
a->num += 2;
}
void main() {
struct Bthat b = {0};
b.b_num = 5;
b.b_str = "In hiss eeaarrrr...";
do_stuff(&b);
}
In other words, if the layout/ordering of initial fields of 2 structs is identical, can I modify instances of either struct by casting them to only one of the two types/structs, as long as I limit myself to only modifying the initial "identical" fields?
I believe that somewhere in the HTSlib code, Marshall, Li and/or Bonfield do something like the above, which... surpised me, so to speak.
Then I ended up in my own code doing something where I have 2 very simmilar structs, and only have to access the initial fields of those structs -- and I thought of what they did.
In short, you can, but it will probably cause UB.
So, with regards to "safely, all the time" -- NO.
However, there's a rule about strict aliasing in the standard.
That means that referencing one type as if it's another 1. breaks strict aliasing and 2. may cause a trap representation propblem.
The C standard does not guarantee that similar/identical structs will have similar/identical layouts in memory.