# Casting bigarray between different kinds, using ctypes, possible problems?

**URL:** <https://discuss.ocaml.org/t/casting-bigarray-between-different-kinds-using-ctypes-possible-problems/8647>\
**Category:** Learning\
**Created:** [October 18, 2021, 1:53pm UTC](https://discuss.ocaml.org/t/casting-bigarray-between-different-kinds-using-ctypes-possible-problems/8647 "2021-10-18T13:53:27Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [October 18, 2021, 1:53pm UTC](https://discuss.ocaml.org/t/casting-bigarray-between-different-kinds-using-ctypes-possible-problems/8647/1 "2021-10-18T13:53:27Z")

</div>

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](https://discuss.ocaml.org/t/cast-bigarray-kind/8469)

The code is:

```auto
(* 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 *) 
    Ctypes.array1 
    ((Bigarray.Array1.dim arr * Ctypes.(sizeof t1)) / Ctypes.(sizeof t2))
    t2_kind
    pc |> fun arr -> 
  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…)

---

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [October 18, 2021, 2:14pm UTC](https://discuss.ocaml.org/t/casting-bigarray-between-different-kinds-using-ctypes-possible-problems/8647/2 "2021-10-18T14:14:14Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![dinosaure](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dinosaure/32/16_2.png) [@dinosaure](https://discuss.ocaml.org/u/dinosaure)\
**Post date:** [October 18, 2021, 2:20pm UTC](https://discuss.ocaml.org/t/casting-bigarray-between-different-kinds-using-ctypes-possible-problems/8647/3 "2021-10-18T14:20:00Z")

</div>

Hi,

A `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 `char`/`int` `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 `bigarray`.

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.

---

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [October 18, 2021, 2:26pm UTC](https://discuss.ocaml.org/t/casting-bigarray-between-different-kinds-using-ctypes-possible-problems/8647/4 "2021-10-18T14:26:51Z")

</div>

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.
