Comment by smj-edison
2 days ago
Not familiar with the idea of "zapped", and I thought that Rust had a similar provenance model?
Working with pointers in Zig is much nicer, since
1. They're not nullable. If you want a nullable pointer, you would use `?*Object` instead of `*Object`.
2. They distinguish between single item and multi-item pointers. `*u8` is a pointer to a single u8, so I couldn't add to it or index it. `[*]u8` is a multi-item u8, which you can index.
3. Pointers track their alignment. I could make a pointer with `*align(128) Object` if I wanted to tag the bottom bits for example. Zig will require casts when changing alignment, for example casting from `*Object`.
4. Everyone uses slices when possible, pretty much Rust's slices.
5. A smaller detail, but there are sentinel pointers/slices, where you guarantee that the last item is a certain things. For example, a C string would be `[*:0]u8`, because it ends with 0.
Today the C and C++ standards do not have a provenance model. The model Rust chose is certainly related to the PNVI-ae-udi model proposed for C, in particular "Provenance Not Via Integers" is a core choice in both schemes. Martin Uecker (who has commented elsewhere in this thread) would I think say they're more similar than I would and he is an expert in this area as he co-authored the C proposal.
Zap isn't much related to provenance, it's more of a difference in philosophy about what pointers are for. With zap they're a very bare bones reference type, they always refer to things which exist and that's all, it's important that they never point anywhere without in fact referencing a thing. Without zap most of the behaviour you associate with hardware addresses works, you can do arithmetic on them, including atomic compare operations, you can use them as parameters to MMIO features and so on. Since C doesn't have any other reference types their role in C makes sense, in Rust and C++ of course actual reference types also exist.