Converting between type and immutable with the same layout

question

#1

I want to convert a mutable type to an immutable type with the same layout, with the immutable type not having a constructor. Is the code below a safe way to do so?

type MutableFoo
  ptr::Ptr{Void}
end

immutable ImmutableFoo
  ptr::Ptr{Void}
end

a = MutableFoo(C_NULL)
b = unsafe_load(reinterpret(Ptr{ImmutableFoo}, (pointer_from_objref(a))))


#2

It’s possible (though shouldn’t happen in most cases) to have a free’d before the unsafe_load.


#3

OK, so as long as a keeps referring to the original mutable it’s fine, right?


#4

a is the original mutable? I just mean that unsafe_load(reinterpret(Ptr{ImmutableFoo}, (pointer_from_objref(a)))) does not guarantee that a will be valid when you read it.

a also doesn’t reference any other ojects. In fact, it can be bad if it does.


#5

Yes, a is the original mutable, convention will be that this is the placeholder to prevent GC and it should be kept or the object (from C++ in this case) stored in the void pointer will be deleted by the finalizer attached to a. This is in fact an implementation detail for referencing C++ objects. Since MutableFoo and ImmutableFoo are both created using the C API, they have no constructor attached (and I couldn’t find a way to attach one from C) so this hack allows me to convert to the stack-allocated “reference type” without using ccall.


#6

A simpler, more common solution is to define that
MutableFoo = Ref{ImmutableFoo}