-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
I've stumbled across this unfortunate inconsistency:
help?> Ptr
search: Ptr Cptrdiff_t CapturedException splitdrive pointer pointer_from_objref escape_string splitdir
Ptr{T}
A memory address referring to data of type T. However, there is no guarantee that the memory is actually valid,
or that it actually represents data of the specified type.
julia> supertype(Ptr)
Ref
help?> Ref
search: Ref WeakRef prevfloat chopprefix UndefRefError GlobalRef uppercasefirst lowercasefirst
Ref{T}
An object that safely references data of type T. This type is guaranteed to point to valid, Julia-allocated
memory of the correct type. The underlying data is protected from freeing by the garbage collector as long as
the Ref itself is referenced.
[...]In essence, we document that Ref{T} is guaranteed to point to valid julia allocated memory, which is not at all true of Ptr{T}, but Ptr{T} <: Ref{T} still holds. There are other problems, like Ptr not having getindex defined, as the Ref docstring claims:
julia> a = [1,2,3];
julia> p = pointer(a)
Ptr{Int64} @0x00007fe5bfbfc9f0
julia> p[]
ERROR: MethodError: no method matching getindex(::Ptr{Int64})So at minimum, Ptr doesn't fulfill the API guaranteed by Ref{T} per the docstring.
We could change the docstring of Ref to Ref(x), and mention that the Ref abstract type does not make such a guarantee. Another option would be to change the name of the Ref type to something else (AbstractRef?) and only keep the Ref function/type around as a shorthand for RefValue, which is what it does now anyway (see @edit Ref(1)). To keep the API the same, it would change from this:
Ref{T}Ptr{T}RefValue{T}RefArray{T}
to this:
AbstractRef{T}Ptr{T}Ref{T}RefValue{T}RefArray{T}
The issue with that is that we don't know whether someone relies on Ptr{T} <: Ref{T} somewhere (which they shouldn't, I think).