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 <[email protected]> wrote:
> On Tue, Feb 21, 2017 at 2:53 PM, Caleb Spare <[email protected]> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.