On Thu, Mar 23, 2017 at 9:16 AM, Caleb Spare <cesp...@gmail.com> wrote: > > 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).
That is an interesting point. I don't think there is anything keeping s alive here. I think this isn't quite the same as the example in the docs, because that example is assuming that you are doing to use s after setting the fields--why else would you be doing that? In this case it does seem theoretically possible that s could be freed between the assignment to h and the use of h.Data. With the current and foreseeable toolchains it's a purely theoretical problem, since there is no point there where the goroutine could be preempted and the fact that s is no longer referenced be detected. But as a theoretical problem it does seem real. One fix would be something like p := &s h := (*reflect.StringHeader)(unsafe.Pointer(p)) sh := (*reflect.SliceHeader)(unsafe.Pointer(&v)) sh.Data = h.Data sh.Len = ... sh.Cap = ... runtime.KeepAlive(p) 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.