C will never stop you from making mistakes
  struct Meow* p_cat = (struct Meow*)malloc(sizeof(struct Meow));
  struct Bark* p_dog = p_cat;

> Most compilers warn, but this is standards-conforming ISO C code that is required to not be rejectedBollocks. That is a constraint violation, ISO C requires a diagnostic for it, and ISO C allows that diagnostic to be an error. The constraint is in the section "Simple assignment", which contains "One of the following shall hold:" followed by a list detailing when assignments are valid. Pointers to different structure types on the LHS vs the RHS are nowhere in that list.