I thought that's handled by the inhdr.Cap % 8 == 0 check. Isn't inhdr.Data essentially a pointer into memory with inhdr.Cap showing the size of the allocated region?
On Monday, February 27, 2017 at 2:14:46 PM UTC-5, xingtao zhao wrote: > > I think you need to check if inhdr.Data is aligned with 8 bytes as well. > > On Sunday, February 26, 2017 at 2:54:00 PM UTC-8, Bill Katz wrote: >> >> Hi, >> >> We'd like to do a zero-copy conversion of []byte to []uint64 where the >> underlying memory for the byte slice is properly aligned for N uint64 >> values. After looking at (6) in the unsafe package documentation >> <https://golang.org/pkg/unsafe/#Pointer>, I'm wondering if the code >> below is valid because I only use reflect.SliceHeader as pointers, and it >> seems to fit pattern 6. >> >> https://play.golang.org/p/FxxKIK08pX >> >> package main >> >> import ( >> "fmt" >> "reflect" >> "unsafe" >> ) >> >> func byteToUint64(b []byte) (out []uint64, err error) { >> inhdr := *(*reflect.SliceHeader)(unsafe.Pointer(&b)) >> if inhdr.Len % 8 != 0 { >> err = fmt.Errorf("cannot convert non-aligned []byte length (%d) to >> []uint64", inhdr.Len) >> return >> } >> if inhdr.Cap % 8 != 0 { >> err = fmt.Errorf("cannot convert non-aligned []byte capacity (%d) to >> []uint64", inhdr.Cap) >> return >> } >> outhdr := *(*reflect.SliceHeader)(unsafe.Pointer(&out)) >> outhdr.Len = inhdr.Len / 8 >> outhdr.Cap = inhdr.Cap / 8 >> outhdr.Data = inhdr.Data >> out = *(*[]uint64)(unsafe.Pointer(&outhdr)) >> return >> } >> >> func main() { >> b := make([]byte, 24) >> u, err := byteToUint64(b) >> if err != nil { >> fmt.Println(err) >> } else { >> fmt.Printf("b: %v\n", b) >> fmt.Printf("u: %v\n", u) >> fmt.Printf("len(u) = %d, cap(u) = %d\n", len(u), cap(u)) >> u[0] = 15 >> fmt.Printf("Set u[0] to 15\n") >> fmt.Printf("b: %v\n", b) >> fmt.Printf("u: %v\n", u) >> u[2] = 255 >> fmt.Printf("Set u[2] to 255\n") >> fmt.Printf("b: %v\n", b) >> fmt.Printf("u: %v\n", u) >> } >> } >> >> Outputs: >> >> b: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] >> u: [0 0 0] >> len(u) = 3, cap(u) = 3 >> Set u[0] to 15 >> b: [15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] >> u: [15 0 0] >> Set u[2] to 255 >> b: [15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0] >> u: [15 0 255] >> >> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.