# \`unsafe\_pointer\_to\_objref(::Ptr{T})\` is not type stable

**URL:** <https://discourse.julialang.org/t/unsafe-pointer-to-objref-ptr-t-is-not-type-stable/45256>\
**Category:** Internals & Design\
**Created:** [August 20, 2020, 9:14am UTC](https://discourse.julialang.org/t/unsafe-pointer-to-objref-ptr-t-is-not-type-stable/45256 "2020-08-20T09:14:49Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![mgkuhn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgkuhn/32/6276_2.png) [@mgkuhn](https://discourse.julialang.org/u/mgkuhn)\
**Post date:** [August 20, 2020, 9:14am UTC](https://discourse.julialang.org/t/unsafe-pointer-to-objref-ptr-t-is-not-type-stable/45256/1 "2020-08-20T09:14:50Z")

</div>

Example code:

```julia
mutable struct Foo{T}
    v::Vector{T}
    n::Int
    # possibly lots more fields, which I don't want
    # to have to copy each time with unsafe_{load,store!}
end

function demo()
    a = Foo{Int64}([1], 2)
    pa = pointer_from_objref(a) # gives me an untyped Ptr{Nothing}
    # pa passed on to a C library ...
    # ... pa received back through a C callback function
    tpa = convert(Ptr{Foo{Int64}}, pa) # C callback function restores type
    # tpa[].n += 1 is not allowed
    na = unsafe_pointer_to_objref(tpa)
    na.n += 1
end
demo() == 3 && @code_warntype demo()

```

`@code_warntype demo()` shows this function to be type unstable, returning `::Any` instead of `::Int64`:

```julia
Variables
  #self#::Core.Compiler.Const(demo, false)
  a::Foo{Int64}
  pa::Ptr{Nothing}
  tpa::Ptr{Foo{Int64}}
  na::Any

Body::Any
1 ─ %1 = Core.apply_type(Main.Foo, Main.Int64)::Core.Compiler.Const(Foo{Int64}, false)
│ %2 = Base.vect(1)::Array{Int64,1}
│ (a = (%1)(%2, 2))
│ (pa = Main.pointer_from_objref(a))
│ %5 = Core.apply_type(Main.Foo, Main.Int64)::Core.Compiler.Const(Foo{Int64}, false)
│ %6 = Core.apply_type(Main.Ptr, %5)::Core.Compiler.Const(Ptr{Foo{Int64}}, false)
│ (tpa = Main.convert(%6, pa))
│ (na = Main.unsafe_pointer_to_objref(tpa))
│ %9 = Base.getproperty(na, :n)::Any
│ %10 = (%9 + 1)::Any
│ Base.setproperty!(na, :n, %10)
└── return %10

```

with `::Any` highlighted in red. This seems due to the definition in `Base` of

```julia
unsafe_pointer_to_objref(x::Ptr) = ccall(:jl_value_ptr, Any, (Ptr{Cvoid},), x)

```

Is is not possible for `Base` to implement a method

```julia
unsafe_pointer_to_objref(x::Ptr{T})::T

```

for which the compiler can infer the return type being `T`?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 20, 2020, 12:33pm UTC](https://discourse.julialang.org/t/unsafe-pointer-to-objref-ptr-t-is-not-type-stable/45256/2 "2020-08-20T12:33:57Z")

</div>

When you are passing pointers through C, you should just use the correct return type, e.g. `Ref{Foo{Float64}}` instead of using `unsafe_pointer_to_objref`.
