Home > Mobile >  Is comparing pointers across allocations well-defined in Rust?
Is comparing pointers across allocations well-defined in Rust?

Time:03-08

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.

  • Related