I have a pointer buf: *const T
pointing to the start of an allocation of n
elements of T
, and I define the following check:
let in_alloc = buf <= ptr && ptr < unsafe { buf.add(n) };
Is it guaranteed that in_alloc
is true
for any ptr
that lies in the allocation of buf
, and false
in any other case? We may assume that ptr
is a valid pointer to a T
object (so not misaligned/null/dangling), however it may or may not be from the same allocation as buf
. Finally we may assume T
is not zero-sized.
CodePudding user response:
Answering the title, comparing any two pointers is well-defined since pointers implement Ord
.
With pointers being totally ordered, the body of the question follows easily from this. You have a set of n
distinct pointers, starting at buf 0
and ending at buf (n - 1)
. If ptr
is less than buf
it can't be equal to any of them. If ptr
is greater than buf (n - 1)
it also cannot be equal to them. If ptr
is one of them, both expressions evaluate to true.
CodePudding user response:
According to the official documentation, it is valid to produce a raw pointer one byte past the allocation of the object the pointer points to (so 1). Obviously you cannot dereference the pointer, but it can be used for comparisons, eg. for bounds checking in a loop.
Beyond that, it's undefined behaviour, so you're not guaranteed anything at all. In your case adding an arbitrary offset to the pointer would not be a good idea for this reason.
So, to answer more specifically, it will return the value you expect as long as buf.add(n)
points to an address that is at most 1 byte past the allocation of the object buf
points to.
See https://doc.rust-lang.org/1.59.0/std/primitive.pointer.html#method.offset for more details.
CodePudding user response:
Yes, this code works as you would except. Comparing pointers that point to different allocations should behave as expected as implied by the documentation of std::ptr::eq.