Comment by debugnik

1 month ago

> you have to turn off strict aliasing because inheritance is implemented by the old "common meta struct as first member" idiom

You shouldn't have to turn off strict aliasing for that, struct pointers are allowed to alias pointers to their first member. Unless I'm missing some awkward compatibility rule that mruby breaks.

You do need to turn off strict aliasing for that, because mruby uses `struct RObject { RB_OBJECT_HEADER; ... }` and `struct RHash { MRB_OBJECT_HEADER; ... }` (where MRB_OBJECT_HEADER begins with `RClass `). You can alias objects of both types as an `RClass `, but you can't alias them as one-another, converting RHash to RObject. According to my reading of the strict aliasing rules[0], the aliasing would be legal if one of the types literally contained the other, or if they were being accessed through a union. The "compatible types"[0] section requires the types to be exactly the same in layout, not just starting as the same. It's not safe to cast incompatible structs to one another just because they have the same initial members, unless you are accessing them through a union (C11 6.5.2.3p6). Optimization can cause UB when working with mruby if strict aliasing is enabled.

[0] https://en.cppreference.com/w/c/language/object.html#Strict_... [1] https://en.cppreference.com/w/c/language/compatible_type.htm...

  • Oof, I get it now. I was expecting RHash to start with an actual RObject, not just the same members. I too read the "compatible first member" rule as not applying here, so I agree it breaks strict aliasing.