I have some code that allows to cast a bigarray between different kinds, using ctypes. The code is based on the earlier discussion here: Cast Bigarray kind
The code is:
(* t1 and t2 are ctypes kinds; t2_kind is a normal bigarray kind *)
let coerce_bigarray1 t1 t2 t2_kind arr =
Ctypes.bigarray_start Ctypes.array1 arr |> fun (pi:'t1 Ctypes.ptr) ->
Ctypes.(coerce (ptr t1) (ptr t2) pi) |> fun (pc:'t2 Ctypes.ptr) ->
Ctypes.bigarray_of_ptr (* this function forces C layout *)
((Bigarray.Array1.dim arr * Ctypes.(sizeof t1)) / Ctypes.(sizeof t2))
pc |> fun arr ->
I began to get scared of this code. What if I cast from a bigarray of char to a bigarray of OCaml-native int? And what if the chars were such that one of the resulting ints was actually interpreted as a pointer? And what if I then accessed that value in the int bigarray? And GC kicked in? Would the GC interpret the integer as a pointer and wrongly follow it, causing a segfault?
(It turned out the segfault was actually a stack overflow, but I’m still worried about the situation described…)
I guess that, when accessing the int bigarray, there is some code to ensure that an array entry that resembles a pointer is actually interpreted as an int?
bigarray for the OCaml point-of-view (specially for the GC point-of-view) is an opaque value which exists into the C heap. Then, a small object exists into the OCaml heap to refer to this value - note that this object is associated to a finalizer to correctly
free the value into the C heap.
That mostly means that the GC will never follows what you have into your
bigarray. Then, the kind type express only how to transform a value into your
bigarray into an OCaml value. For instance, if your bigarray is a
bigarray, it will use
leaq to put the GC bit into the returned value. For values such as
nativeint, it will, obviously (regardless some optimizations) allocates the
nativeint into the OCaml heap and set it to the right value from the
So you can safely say that the GC will never follow what it can find into your
bigarray as an opaque value for its point of view.
Thank you for your reply. So, the bigarray is opaque, and accessing an element in an int bigarray will ensure that the element is treated as an int (by setting the lowest bit 0). Thanks, that makes sense.