It's usually simplest to write an expression like
s := (*[1 << 20]Tag)(Carr)[:arrLength:arrLength]
That will give you a slice whose backing array is the C array, without
requiring any copying. Of course you then have to make sure that C
array lives on the heap as least as long as the slice does. If that
is an issue, then write
s2 := make([]Tag, arrLength)
copy(s2, s)
To be clear, this assume there are fewer than 1 << 20 entries in the
array, so adjust as needed.
The vet errors for your code are false positives, assuming that cArr
is allocated in C memory. That said, it's easy to avoid them by
writing code like
q := unsafe.Pointer(cArr)
for i := 0; i < arrLength; i++ {
p := (*Tag)(q)
ret = append(ret, int(*p))
q = unsafe.Pointer(uintptr(q) + unsafe.Sizeof(q))
}
The point is: always keep pointers as pointers, except in expressions
that convert to uintptr and back in a single expression.
Ian