# Isbits object lifetimes on 0.7

**URL:** <https://discourse.julialang.org/t/isbits-object-lifetimes-on-0-7/7482>\
**Category:** General Usage\
**Created:** [December 3, 2017, 10:30pm UTC](https://discourse.julialang.org/t/isbits-object-lifetimes-on-0-7/7482 "2017-12-03T22:30:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [December 3, 2017, 10:30pm UTC](https://discourse.julialang.org/t/isbits-object-lifetimes-on-0-7/7482/1 "2017-12-03T22:30:36Z")

</div>

I’ve been chasing down a segfault in SCS.jl on 0.7 (0.7.0-DEV.2725), and I believe I’ve narrowed it down to the following issue:

```julia
# Not standalone code
struct A
val::Float64
... # lots of plain data fields (isbits(A) == true)
end

struct B
a::Ptr{A}
end

function foo_()
    a = Ref(A(10.0, #= extra fields... =#))
    b = Ref(B(Base.unsafe_convert(Ptr{A}, a)))

    # foo modifies b and a
    ccall(:foo, Void, (Ptr{B},), b)
    # the value of unsafe_load(b[].a).val is corrupted when foo first reads it ...
    # but not if the following line in uncommented
    # @show a
end
foo_()

```

I’m inferring from this that the compiler is seeing that `a` is not needed after the construction of `b`, and hence it aggressively “frees” the memory that backs `a` even within the scope of `foo_`. Is there a proper way to extend the lifetime of `a` past the `ccall`?

Edit: related discussion at [Help with ccall to a clib function](https://discourse.julialang.org/t/help-with-ccall-to-a-clib-function/5747)

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 3, 2017, 10:58pm UTC](https://discourse.julialang.org/t/isbits-object-lifetimes-on-0-7/7482/2 "2017-12-03T22:58:20Z")

</div>

I am kinda surprised that this compiles at all. I always thought that taking addresses of stack-objects (local variables) was forbidden/undefined in julia.

A very simple workaround is to create a boxed A and B, e.g. by putting them into an array. This costs an allocation, so you should store them someplace for reuse if you plan to call foo\_() often.

A more explicit workaround would be to @gc\_preserve a until the ccall is finished. But until someone more knowledgeable chimes in to tell us that this is allowed, I would not trust taking addresses of any stack objects…

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [December 3, 2017, 11:15pm UTC](https://discourse.julialang.org/t/isbits-object-lifetimes-on-0-7/7482/3 "2017-12-03T23:15:31Z")

</div>

`@gc_preserve` seems to be used in similar `ccall` situations within `Base`, and it fixes the segfaults, thanks! I’m surprised it’s not mentioned in the “Calling C and Fortran code” documentation (unless there’s a more official workaround).

> [@foobar\_lv2](#):
>
> A very simple workaround is to create a boxed A and B, e.g. by putting them into an array.

My understanding was that using `Ref` should be equivalent to but more efficient than creating a 1-element array.

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [December 4, 2017, 12:58am UTC](https://discourse.julialang.org/t/isbits-object-lifetimes-on-0-7/7482/4 "2017-12-04T00:58:02Z")

</div>

IIUC the problem is the `Base.unsafe_convert(Ptr{A}, a)` without the `@gc_preserve` since the GC “loses” track of the Ptr. Still the definition of `B` is problematic since I don’t think you can use `@gc_preserve` in situations like

```julia
function f()
    a = Ref(A(10.0, #= extra fields... =#))
    b = Ref(B(Base.unsafe_convert(Ptr{A}, a)))
    return b
end

```

The GC is now free to get rid of `a`…

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [December 4, 2017, 1:27am UTC](https://discourse.julialang.org/t/isbits-object-lifetimes-on-0-7/7482/5 "2017-12-04T01:27:10Z")

</div>

Yes, but that’s not the situation here. The fix is now in action at [https://github.com/JuliaOpt/SCS.jl/blob/f1e41834ef8488c5d26dee16e71b39626f0b84f5/src/c\_wrapper.jl#L66](https://github.com/JuliaOpt/SCS.jl/blob/f1e41834ef8488c5d26dee16e71b39626f0b84f5/src/c_wrapper.jl#L66) for anyone who wants to see a more complex example.
