Similar to #863 (when slicing with a comptime length, result type should be pointer to array), pointers to arrays should support pointer arithmetic. The result type is a pointer to an array with a smaller len, and appropriate alignment. Compile error happens if you go out of bounds.
Ran into this working on https://github.com/andrewrk/zig-general-purpose-allocator/. I correctly used a *align(page_size) [page_size]u8 type, but then had to go back and use the worse option [*]align(page_size) u8 due to not having pointer arithmetic.
In general, users should prefer pointers to arrays when the length is compile time known, and the language should support that preference.
Isn't this the same as #863? With that, you could do:
const arr: [50]u8 = undefined;
const arr_ptr = &arr;
_ = @typeOf(arr_ptr[4..]); // *[46]u8
_ = @typeOf(arr_ptr[10..20]); // *[10]u8
Good point, I hadn't considered that. Do you think we should not support pointer arithmetic then?
@andrewrk Only + could realistically be supported as - would be unsafe. So why have 2 ways of doing the same thing? :)
So why have 2 ways of doing the same thing?
Actually I have an answer to that. In generic code you would expect to use + on both an unknown length pointer and a pointer to an array. It's generally supposed to be better to have a pointer to an array than an unknown length pointer wherever possible. So the argument is that if it works for unknown length pointer, and it could work safely for a pointer to array, then it should work.
Note that pointer arithmetic currently compiles but does the wrong thing. So this is a pretty high priority issue.
@andrewrk
If you want to allow generically "getting rid of" the first elements of a slice, ptr to statically-sized array, or unknown-size ptr, why not just allow x[i..] for unknown-size ptrs instead? (and would be analogous to ptr arithmetic)
That follows the existing convention of letting [*]T use indexing-syntax, without having to add 2 ways of reslicing a static-array or making a special case for pointer arithmetic.
It would make more sense to allow both x[i..] and x + i for unknown-size pointers, since they conceptually represent similar operations if you think of [*]T like a regular c-style array pointer.
Also, we already have precedent for x[i..] not necessarily returning []T, such as slicing a statically-sized array with a comptime-known range. This has shown to be very useful, and I think this would too.
With this change, *[n]T can no longer be considered a pointer to [n]T -- it is special-cased as a kind of pointer to T, breaking separability. What if we have *[n][m]T? Does pointer arithmetic advance by the size of [m]T or of T? Either way, you break some expectation. Furthermore, even with this change, *[n]T does not behave like [*]T -- it still does not allow subtraction.
I think a much better solution is to allow x[n..] for [*]T, returning the equivalent of x + n -- that way generic code is happy, and there's no special cases in the type system. @andrewrk, I implore you to reconsider this change.
Thanks for the counter-proposal - I've removed the accepted label for re-consideration.
In the meantime, afaef3619458e6e8c79c15944fa871ca6cc5a58a makes pointer arithmetic on arrays a compile error, so this is no longer a miscompilation.
This issue can now be demoted to a 0.8.0 issue.
Most helpful comment
With this change,
*[n]Tcan no longer be considered a pointer to[n]T-- it is special-cased as a kind of pointer toT, breaking separability. What if we have*[n][m]T? Does pointer arithmetic advance by the size of[m]Tor ofT? Either way, you break some expectation. Furthermore, even with this change,*[n]Tdoes not behave like[*]T-- it still does not allow subtraction.I think a much better solution is to allow
x[n..]for[*]T, returning the equivalent ofx + n-- that way generic code is happy, and there's no special cases in the type system. @andrewrk, I implore you to reconsider this change.