cpointersmemorystruct

Using the layout of a different struct pointer


TL;DR

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?

Two different structs with initial identical layouts

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?

Why?

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.


Solution

  • 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.