You are misreading. I said to take a char * and then cast it to whatever you want. You can cast it to struct A *. Then you can cast the original char * to struct B *. The compiler will be fine with this since the strict aliasing rule excludes char *.

If you insist on doing what you described, just skip char * and mark the pointer with __attribute__((may_alias)) and then it will be okay. That is a compiler extension that lets you turn off strict aliasing rules.

Ah, I see. Like this:

    char x[sizeof(struct Foo)];
    struct Foo* f = (struct Foo*)&x;
    struct Bar* b = (struct Bar*)&x;

(I can't edit so replying instead.) But this isn't allowed either. You can access a struct Foo variable through a char* pointer but you can't use struct Foo* to access an object whose actual type ("effective type" in the words of the standard) is char array. The standard says:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

— a type compatible with the effective type of the object,

— a qualified version of a type compatible with the effective type of the object,

— a type that is the signed or unsigned type corresponding to the effective type of the object,

— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,

— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or

— a character type.

https://www.iso-9899.info/n1570.html#6.5p7

I realise that many implementations will allow it anyway but if you're relying on that then you may as well fall back to a straight cast from Foo* to Bar*, which is also not allowed in theory.