Comment by rvrb
12 hours ago
`extern` and `packed` container types have well defined layouts. a regular `struct` is an "auto" layout - and the compiler can and will rearrange whenever it wants.
if you need a well defined layout, use `extern`. if your struct makes sense to represent as an integer, use `packed`. I think it is often ill advisable to use `packed` otherwise.
you can explore this yourself on the Type info returned from @TypeInfo(T):
https://ziglang.org/documentation/master/std/#std.builtin.Ty...
https://ziglang.org/documentation/master/std/#std.builtin.Ty...
https://ziglang.org/documentation/master/std/#std.builtin.Ty...
To wit: https://ziglang.org/documentation/master/#extern-struct
> An extern struct has in-memory layout matching the C ABI for the target.
Zig is really good at speaking the C ABI of the target, but the upshot seems to be that it appears there is no stable Zig-native ABI.
If I'm correct, I wonder if there are plans to settle on a stable ABI at some point in the future. I do know that in other languages the lack of a stable ABI is brought up as a downside, and although I've been burned by C++ ABI stability too many times to agree, I can understand why people would want one.
I doubt zig will have stable abi any time soon. It may have some sort of "zig extern" when it gets mature. But stable abi isnt very usful if no-one else can talk it. I have project that uses codegen to effectively implement zig like ABI on top of the C abi.
Heres the kind of code it generates https://zigbin.io/6dba68
It can also generate javascript, heres doom running on browser: https://cloudef.pw/sorvi/#doom.wasm
Andrew Kelley has said relatively recently that there are no plans to introduce a Zig ABI: https://github.com/ziglang/zig/issues/3786#issuecomment-2646...
What's interesting is that the scope of the proposal isn't a Zig-specific ABI, but a codified way of expressing certain Zig concepts using the existing C ABI.
That could be an interesting middle ground.
1 reply →
in practice, as long as you match the version and release mode, it's fine (though you are playing with fire). I pass raw pointers to zig structs/unions/etc from the zig compiler into a dynamically loaded .so file (via dlload) and as long as my .so file is compiled with the same compiler as the parent (both LLVM, in my case) it's peachy keen.
You are still playing with fire as the data inside those pointers may be different even if they are the same type. Zig is free to optimize them in anyway it likes depending on the code that touches them (aka its free to assume they never leave the program).