On Wed, Apr 22, 2020 at 4:33 AM T L <tapir....@gmail.com> wrote: > > On Tuesday, April 21, 2020 at 8:13:17 PM UTC-4, Ian Lance Taylor wrote: >> >> On Tue, Apr 21, 2020 at 8:17 AM T L <tapi...@gmail.com> wrote: >> > >> > And is the runtime.KeepAlive call in the following program essential to >> > keep the correctness? >> > >> > package main >> > >> > import ( >> > "fmt" >> > "unsafe" >> > "reflect" >> > "runtime" >> > ) >> > >> > func main() { >> > a := [6]byte{'G', 'o', 'o', 'g', 'l', 'e'} >> > bs := []byte("Golang") >> > hdr := (*reflect.SliceHeader)(unsafe.Pointer(&bs)) >> > hdr.Data = uintptr(unsafe.Pointer(&a)) >> > >> > runtime.KeepAlive(&a) // Is this line essential here? >> > >> > hdr.Len = 2 >> > hdr.Cap = len(a) >> > fmt.Printf("%s\n", bs) // Go >> > bs = bs[:cap(bs)] >> > fmt.Printf("%s\n", bs) // Google >> > } >> >> I do not think the runtime.KeepAlive is required. Setting the Data >> field using a *SliceHeader should keep the value alive. >> >> Ian > > > > Many thanks for the answers. > > I have another question, which doesn't matter with or without the > runtime.KeepAlive call. > We know that assignment in Go is not atomic. > Is it possible that when the assignment "hdr.Data = > uintptr(unsafe.Pointer(&a))" is half done, > the stack is resized, so the address of a might be changed (assume a is > allocated on stack), > the hdr.Data will be assigned the old invalid value?
First, let me say that it's best to avoid the word "atomic" without clearly explaining what you mean, as it has many different meanings and implications. In this case I think what you mean is that in Go an assignment made by one goroutine may be interleaved with an assignment made by a different goroutine. Or, more precisely, you mean that a goroutine may be interrupted in the middle of doing an assignment, such that another goroutine may observe the assignment as started but not fully completed. Technically, I think you are correct: I don't know of anything in the Go language spec that prohibits a goroutine from being interrupted while partway through the assignment to hdr.Data. But then the Go language spec doesn't discuss stack resizing at all. In practice no Go implementation is going to interrupt an assignment that is only a single memory word. And, of course, it would be invalid for a Go implementation that does stack shrinking or garbage collection to interrupt an assignment of a pointer value. And at the machine level, on a modern processor, an assignment of a uintptr uses the exact same instructions as an assignment of an unsafe.Pointer. So I don't think there is anything to worry about here. 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVmaqFe_9QSKKPFmpdMM8nnDgU%2BZ%2BFcMp09rXbtf5sDJw%40mail.gmail.com.