Is the pointer "at-the-end" still valid?

In 1.80.0 doc, std::ptr::add documentation mentioned that pointers at the end of the same allocated object are valid:

If any of the following conditions are violated, the result is Undefined Behavior:

  • If the computed offset, in bytes, is non-zero, then both the starting and resulting pointer must be either in bounds or at the end of the same allocated object. (If it is zero, then the function is always well-defined.)

This however seems to be removed in 1.81.0 doc, which instead only says that the resulting pointer must be inbound. I couldn't find anything on the section about allocated object either beyond address a must be in range base .. (base + size).

Is this guarantee still valid? The example even mentions vec.as_ptr().add(vec.len()), which would put the pointer at the end of the allocation, and I still see this being utilized within std, e.g., in calculating end in std::slice::as_ptr_range implementation.

If it is no longer valid, is it still ok if ptr::add points to the end of the allocated object and drop without being used, or should I use wrapping_add if that is a possibility?

Yes, they don't just take away permissions like that. It's part of the no breaking changes promise.

The new wording says that the memory range between the pointers before and after add must be in-bounds. I would say that this does allow at-the-end pointers, since the memory range just ends at the end.

3 Likes

The 1.81 documentation that you linked mentions a bit later that:

This implies, for instance, that vec.as_ptr().add(vec.len()) (for vec: Vec<T> ) is always safe.

Which corroberates what @alice said.

EDIT
Sorry I just realized that you mention this yourself, so I imagine that @alice was already able to disperse your douts.

2 Likes