Today I ran into a problem cross-compiling for aarch64 due to the presence of an unused field in a struct. The struct in question is std.os.linux.Flock. For x86_64, it’s defined like so:
The OP’s point seems to be: since these fields are unused, a default value should be set to make them easier to use.
I’m not sure about this. There are two possible ways to initialize unused values: one is to initialize them to 0 (which is consistent with how C initializes unused values), and the other is to initialize them to undefined, which conforms to the unused semantics and reduces the amount of memory copying. However, the specific initialization method is likely controversial, and different unused values may require different initialization requirements in different situations.
(I am pretty sure we are talking about those fields in OP that are named… __unused)
It does feel inconsistent yeah. For example, std.os.linux.sockaddr.in does zero the paddy field.
I think it is just good hygiene to memset an extern struct to zero before sending it elsewhere anyway, just in case there are paddings not expressed with those paddy fields. You should have some wrapper layer around that (like std.posix-style, for adapting OS-errors, passing slices, …), so those little things can go there so you won’t forget to do.
…to get automatic ‘C semantics’ for this type of structs, but I think this is considered controversial nowadays with the .init pattern. I’m not a big fan of using stdlib helpers for things that should actually be language features
Note that at least in C, memsetting a struct doesn’t guarantee that (non-accessible) padding bytes are initialized to zero or stay zero when the struct is copied around since C compilers treat memset, memcpy etc… as compiler builtins nowadays, not as regular function calls, and they are free to replace the set- or copy-operations with individual struct member accesses which don’t cover the padding bytes.
I wouldn’t be surprised if Zig behaves the same (not in this speciifc examples with ‘manual padding’, but for regular padding bytes).
I say yes. It creates a problem which doesn’t need to be there. The default could be undefined or 0, but it’s perverse to make the user assign something to a field which merely happens to exist while providing no functionality.
But this implies that an all-zero Flock is valid, and I doubt that (is pid == 0 allowed? probably not).
A struct which is non-functional if it hasn’t been provided with specific initial values, should not come with the option to easily initialize it without providing those values. That’s why Zig doesn’t implicitly set values like some other languages.
The person who defined the struct is always in a better position to decide what value should go into the unused field. Programmers who’re just using the struct cannot possibly guess how that field will be used in the future.
0 and undefined aren’t the only possible values. -1 might also make sense in certain circumstances, if you anticipate a bitmask defaulting to all true will sit there for example.
Reminds me of where I’ve seen some devs think it’s fine to smuggle data in “unused”, “padding”, and “reserved” fields. (shudder). Whatever you do here, will affect things if you’re using a dependency that plays such schenanigans.