Thanks Ian, that's very helpful. Brief follow-up: does the seeming validity of the code rely at all on the fact that the indicated line is written as a single line? What if, instead, a *StringHeader var were extracted?
func stringToSliceUnsafe(s string) []uint64 { var v []uint64 h := (*reflect.StringHeader)(unsafe.Pointer(&s)) // <-- sh := (*reflect.SliceHeader)(unsafe.Pointer(&v)) sh.Data = h.Data sh.Len = h.Len >> 3 sh.Cap = h.Len >> 3 return v } (Play link: https://play.golang.org/p/BmGtYTsGNY) Does h keep s alive? A strict reading of rule 6 doesn't seem to say that keeping a *StringHeader or *SliceHeader around keeps the underlying string/slice alive (but it's sort of implied by the rule 6 example code, which doesn't refer to s after converting it to a *StringHeader). Caleb On Tue, Feb 21, 2017 at 3:27 PM, Ian Lance Taylor <i...@golang.org> wrote: > On Tue, Feb 21, 2017 at 2:53 PM, Caleb Spare <cesp...@gmail.com> wrote: >> I have a program that uses unsafe in order to coerce some slices to >> strings for use as map keys. (Avoiding these allocations ends up being >> an important performance optimization to this program.) >> >> Here's some example code that shows what I'm doing: >> >> https://play.golang.org/p/Yye1Riv0Jj >> >> Does this seem OK? I've tried to make sure I understand how all the >> unsafe codes fits into the blessed idioms at >> https://golang.org/pkg/unsafe/#Pointer. The part I'm most curious >> about is the indicated line: >> >> sh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data // <--- >> >> This is a double-application of rule 6: it's a conversion *from* a >> reflect.StringHeader's Data field *to* a reflect.SliceHeader's Data >> field, through an unsafe.Pointer and uintptr. >> >> This code has been working for a long time and appears to continue to >> work, but I've been re-reviewing all my unsafe usage after reading the >> conversation at https://github.com/golang/go/issues/19168. > > I can't see anything wrong with this code. Maybe someone else can. > > Ian -- 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.