Is there a way to enforce read only behavior for a struct field?
The use case is memory mapped registers in a microcontroller.
Is there a way to enforce read only behavior for a struct field?
The use case is memory mapped registers in a microcontroller.
There is not. The proposal for private fields (which is related but not the same) was closed with this explanation.
The answer to that is probably similar to what you’ll hear for read-only fields. Basically, the core team believes that documentation, field names, and (in the future) tooling is a sufficient solution to field access “restrictions.”
No, not directly. If the struct itself is mutable its fields are too.
You can however use a const pointer to the struct or define getters to avoid accidental mutation.
For memory mapped registers I think a common approach is to hide the address altogether and define a read
method for safe access. Take a look at how microzig does it:
EDIT: struct fields are indeed not mutable if the struct is const, see reply
no a constant value does not let you mutate fields.
const
is not shallow, except for pointers which have their own constness
Yeah you’re right about that of course. I just assumed the struct has to be a var because of other fields/its parent container then you could use a const pointer to it or a getter function.
I think the core of the issue here is that both const
and var
propagate recursively through all fields of a type. There is no way to make one field immutable and another one mutable. It’s all or nothing.
The only way to effectively encode const
ness into a type are const
pointers, otherwise it’s always up to the user whether to instantiate the type as var
or const
. And even then, the user can still just mutate the pointer itself.
Or you can make the correct usage ‘obvious’ by e.g. providing a read()
method, which is what is intended by the Zig core team AFAIK.
Thanks for the responses and proposed solutions.
With respect to the private field discussion this seems like a separate issue in my opinion. I am not interested in hiding a field. I would just like a compile time check that no write/assignments are performed to that field.
It would be nice to be able to use const for a field. That to me seems like a consistent use of the keyword (I know that is not for me to say but still).
But I defer to our benevolent overlords on the issue.
FWIW would like to see a filesystem-like access rules system that’s very different from the typical public/private/protected thing in OOP languages, but this would probably be a whole new ‘data centric’ programming language.
The idea is that your whole application state would be organized in a single nested globally visible struct (similar to how code is organized in a single big module tree with a root module at the top).
…then at some central place you define access rules (which parts of the code have read-only, read-write - and maybe no-access - to specific locations in the data tree).
tbh I don’t see the point of having anything not public in a programming language.
Restricting data visibility isn’t as important as readonly access, but ‘everything visible to everybody’ will massively increase refactoring friction in large code bases (because when something is accessible, it will be used, no matter what the documentation says). E.g. something like Zig’s pub
to restrict inter-module visibility is the bare minimum IMHO.
But if all data is organized in a single filesystem-like struct, something similar to pub
may be needed to shield off specific parts of the data from specific parts of the code.
One might even argue that data visibility is more important than code visibility (e.g. all functions are public but data access is restricted), e.g. if a caller tries to call a public helper function with data the caller may not access, compilation will fail, while another part of the code may call the same function with the same data just fine.
But yeah, this is quite esoteric, not very Zig related and at best a ‘brainstorming topic’