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.

Reply via email to