Pointer Arithmetic


#1

I can add or subtract an offset from a pointer using “.offset(x)”. What is the best way to calculate the difference between two pointers, as you would in C/C++, for example to calculate how many array elements there are between two pointers into the array. It is important the following identity is preserved: y = x.offset(d), d = y - x ?


#2

The best I have been able to come up with, and maybe this is the only way, is to covert each pointer to a usize, subtract and then divide by the size of the object using mem::size_of::()


#3

If you have two indexes, you can slice the array, and ask for its len().


#4

Exactly. In general, you should avoid using offset(x). In particular, instead of s.as_ptr().offset(x), one should do s[x..].as_ptr() because then it will be bounds-checked. @leonardo’s suggestion for the length of the difference of two pointers would then become s[x..y].len().


#5

In general I don’t want every operation bounds checked, I want to check bounds at specific points. For example when binary searching using a pair of pointers into an array (because it is faster than using indexes) all I need to do is check both pointers are in bounds (in fact less than that, that the start pointer is between the beginning of the array and the end pointer, and that the end pointer is before the end of the array) before I start the binary search, and by the properties of the algorithm I know it will not go out of bounds. For example the average operation to find the mid point of two pointers cannot go out of bounds if the original pointers are in bounds.

Edit: There is something else interesting here. and that is whilst addition of pointers does not makes sense when combined with division, all of a sudden it does. Adding two pointers the result is a typeless ‘thing’ which is not a pointer, but the average of two pointers is a pointer.


#6

I discussed this over on LtU where i got to the point of deciding a pointer space is a one dimensional vector space, and that pointer averaging is an example of an Affine-Sum. We can define an affine space over the vector space if we want. So that’s a topological model of pointers, but I got stuck trying to find an algebraic equivalent. It was then pointed out to me that a pointer is a “Torsor”.

So now I have an algebraic model for pointers. Interestingly in one dimension a Cartesian affine frame is a point plus a single weight, which looks to me like an address and an offset. In this case Rusts standard iterators are a Cartesian affine frame for the memory vector space.