
"Eregon (Benoit Daloze) via ruby-core" <ruby-core@ml.ruby-lang.org> wrote:
I would be more worried about the C compiler, if the C compiler figures out a pointer is casted to "unrelated" struct types it might consider that as undefined behavior and do anything.
It's not undefined, every platform defines its own C ABI. Any toolchain which ignores that ABI cannot interoperate at all (which is fine for cases where you don't need interop) Consider 1) how many languages/runtimes call C libraries. Now consider 2) how many languages/libraries get called by C. 1 is common, 2 is rare and needs explicit instructions in the non-C language (e.g. extern "C" in C++ headers). gcc and clang generate objects from C which can safely be linked by the others' linker. This isn't true for C++ at all. FFI is completely dependent on a stable ABI.
But I suspect that's explicitly not undefined behavior, because C has no notion of struct types being related or not, and there is likely tons of software using structs "inheriting/extending" another smaller struct.
It might not explicitly be allowed either because I guess the fully correct way to do this is using a union of both structs, and not casting to a specific struct directly then.
FFI and Rust would not be able to use C libraries if the C toolchain were told to violate its platform ABI. Consider "struct sockaddr *" use in C standard library: Functions like accept, connect, bind, getpeername, getsockname, etc. all take a "struct sockaddr *" arg, but callers are expected to allocate one of sockaddr_{in,in6,un,storage,...} to call them. No unions are forced on a user for those sockaddr functions. (I end up defining unions myself in what little C code I maintain, but that's my choice for maintainability). Same for POSIX fcntl locks, various ioctls, getsockopt/setsockopt, or any other function which takes multiple struct types. You can use FFI or syscall+pack/unpack on all of those functions. To make things more explicit, gcc and clang has transparent_union which is intended to help document and preserve ABI compatibility: https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Common-Type-Attributes.html#in...