Open Urgau opened 2 weeks ago
cc @rust-lang/opsem
Also see https://github.com/rust-lang/unsafe-code-guidelines/issues/478 (but note that some things changed since the issue was opened so part of the information there is outdated).
The reference has a definition of dangling pointers.
Right, so somewhat confusingly ptr::dangling
on a ZST does actually produce a non-dangling pointer.
The documentation for ptr::dangling
even explicitly says that it produces a dangling pointer (which is maybe false?). And then it goes to say that "the pointer value may potentially represent a valid pointer to a T
" (which is false for non-ZST types, due to provenance).
Documentation from the reference:
A reference/pointer is “dangling” if not all of the bytes it points to are part of the same live allocation (so in particular they all have to be part of some allocation). If the size is 0, then the pointer is trivially never “dangling” (even if it is a null pointer).
This implies that a pointer points to a range of addresses, depending on the type, and whether a pointer is dangling depends on the type.
Documentation from std::ptr
:
We say that a pointer is “dangling” if it is not valid for any non-zero-sized accesses. This means out-of-bounds pointers, pointers to freed memory, null pointers, and pointers created with NonNull::dangling are all dangling.
This implies that whether a pointer is dangling or not doesn't depend on the type.
These two definitions are contradictory.
"may potentially" is definitely true, it doesn't say "will always" after all.
But yeah "is dangling" in the ptr::dangling
docs uses a different definition of "dangling" than the reference. There are two reasonable definitions and we don't have a clear term to distinguish them:
T
that doesn't point to at least size_of::<T>
bytes of allocated memoryWe need to choose a different term for one of these.
I just realized that ptr::dangling
and the (recently merged) dangling_pointers_from_temporaries
lint will both become stable in 1.84, with different uses of "dangling pointer", this is unfortunate, it would be good to clear this situation before they become stable.
NonNull::dangling
is stable since forever, ptr::dangling
just matches that. So I don't think there's any point in trying to pick a different name for ptr::dangling
.
But Cc @rust-lang/libs-api in case they disagree
That's a good point. The lint name however can still be changed (even after 1.84).
Location
There are several places this applies, e.g.:
std::ptr::dangling
std::ptr::from_ref
(in the examples)dangling_pointers_from_temporaries
lintSummary
We have several place in the standard library or as part of lints where we use the term "dangling pointer" without defining it anywhere.
We should have a place where we define what that is, ideally in the standard library, in it's own section, maybe under
std::ptr
, so it can be referenced elsewhere.It should probably have a definition, followed by some bad examples (and maybe how to fix them).
Wikipedia has article on the subject, I don't know if it could serve as a base for our documentation but it may be worth checking it.
Steps