3

In the CGO section of the Golang Wiki, there is an article that explains how to create a Go slice backed by a C array. In the article there is a code snipped that details the conversion and most important statement in that snippet is the following:

slice := (*[1 << 30]C.YourType)(unsafe.Pointer(theCArray))[:length:length]

Everything in the statement makes sense to me except the [1 << 30] part. Can you please explain to me why this is needed?

Liam Kelly
  • 3,524
  • 1
  • 17
  • 41

1 Answers1

3

The array size, 1 << 30, must be greater than or equal to any value of the length variable.

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    type YourType byte
    theCArray := &[8]YourType{}
    const arrayLen = 1 << 30

    {
        length := arrayLen

        fmt.Println()
        fmt.Println(arrayLen, length)
        fmt.Println()
        slice := (*[arrayLen]YourType)(unsafe.Pointer(theCArray))[:length:length]
        fmt.Println(len(slice), cap(slice), slice[:8])
    }

    {
        length := arrayLen + 1

        fmt.Println()
        fmt.Println(arrayLen, length)
        fmt.Println()
        // runtime error: slice bounds out of range
        slice := (*[arrayLen]YourType)(unsafe.Pointer(theCArray))[:length:length]
        fmt.Println(len(slice), cap(slice), slice[:8])
    }
}

Playground: https://play.golang.org/p/e4jv8jfU_WI

Output:

1073741824 1073741824

1073741824 1073741824 [0 0 0 0 0 0 0 0]

1073741824 1073741825

panic: runtime error: slice bounds out of range

goroutine 1 [running]:
main.main()
    /tmp/sandbox576164402/main.go:30 +0x320
peterSO
  • 158,998
  • 31
  • 281
  • 276