Skip to content

Proposal: Declare null pointer representation(s) as part of the C-ABI (re #1953 ) #1959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rohlem opened this issue Feb 14, 2019 · 2 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@rohlem
Copy link
Contributor

rohlem commented Feb 14, 2019

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?).

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Feb 14, 2019
@andrewrk andrewrk modified the milestones: 0.5.0, 0.4.0 Feb 14, 2019
@andrewrk
Copy link
Member

Discussion here: #1953 (comment)

@andrewrk
Copy link
Member

Here's how it's going to be:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

2 participants