17:07:47|~/tmp
λ bat main.zig
pub const S = extern struct {
x: u256,
};
pub fn f(s: S) void {
_ = s;
}
pub fn main() void {
f(.{ .x = 92 });
}
17:08:02|~/tmp
λ zig build-exe main.zig
main.zig:2:8: error: extern structs cannot contain fields of type 'u256'
x: u256,
^~~~
main.zig:2:8: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible
This makes sense C doesn’t support u256 yet, so there isn’t an ABI which could be used to pass this struct between C and Zig. But what if I don’t care about C ABI per se, and only need a well-defined memory layout (eg, I am describing the data as it exists on the disk / on the network)? Is there a way for me to make a bit-castable Zig struct with an u256 field and a well-defined memory layout, without, at the same time, guaranteeing a particular ABI for cross-language interop?
Yes, when working at such low level, you do need to take into consideration endianness. But the idea was to work with, for instance, a network protocol. The protocol would specify which bit would be the one you’re looking for, so you just define your struct so that the bool matches whatever the protocol specifies.
Here comes the trouble. Speaking of network protocols, TCP/IP requires big-endian while most popular archs (x86, x86-64, aarch64) are little-endian. An explicit conversion is needed. Doing it for arbitrary packed struct is no fun.