Proposal: Declare null pointer representation(s) as part of the C-ABI (re #1953 ) #1959
Labels
proposal
This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone
This is a counter-proposal to #1953 , in the way that I believe it solves all of the issues (/ misconceptions?) mentioned in that discussion. It's basically a more concise, stand-alone summary of my comment over there, in hopes I get my point across (more clearly than before).
The basic idea of this proposal is that
the representation of null pointers is a part of the platform's (/configuration's?) C-ABI
. A null pointer is constructed by casting a 0-valued integer to a pointer type, however its representation may even vary between pointer types.Basis of the recent discussion was the favourable property of C being able to represent a null-state of pointer types without increasing their size, and Zig wants to do that too.
How does C get away with this? Null pointer values, in C, are distinct from all valid pointer values. It is a language-level axiom/assertion/promise that C "sacrifices" this one address in trade. If Zig wants the same behaviour for optional pointers, the simplest solution is to adopt the same null pointer values as the platform's C-ABI, assuming this platform has found a way not to noticeably restrict its C programs.
Note however, that this is only relevant for optional and C-ABI pointers. Non-optional Zig-pointers don't need a null state, and so can represent any thinkable address within pointer size.
One elementary reason why I think this is okay is that there aren't any actual pointer operations defined for null pointers. Loading/Storing to a null pointer, for volatile/atomic/aligned/endian-swapped/usual pointers, is not sensible behaviour, because a null pointer, by its definition, doesn't point anywhere. Pointer arithmetic on an optional pointer is as meaningless as arithmetic on an optional integer. Yes, this does mean that conversions between optional and non-optional pointers (f.e. resulting from pointer arithmetic) require a safety check. This is simply safety-checking behaviour that is undefined in C (as I don't believe that any platform out there skewed their pointer arithmetic just to skip over their null pointer representation), aligns with Zig's goal and is already done all over the place.
What if we have no C-ABI, f.e. on C-less freestanding targets? If there is some platform trick, like an always-invalid pointer representation, we can use that. Otherwise, we could allocate one addressable machine unit (byte/word) for exactly this purpose, acknowledging we never use it. Since Zig compiles with all source code present, maybe it's possible to find this address via a linker script. If not, the platform would need some other way/heuristic to provide the concrete address (perhaps the stack location is known, and very first stack byte is expendable for this use case?).
The text was updated successfully, but these errors were encountered: