Hi,

I am assuming this is true, but I couldn't find a definitive answer yet (or
rather, the answers seems bad): Does a pointer into any part of a value
keep the entire value alive? So, e.g. is this code safe?

type A struct { X int; Y int }
func F() *int {
    a := A{42, 23}
    return &a.X
}
func G() {
    p := F()
    a := (*A)(unsafe.Pointer(p))
    fmt.Println(a.Y)
}

The unsafe.Pointer rules <https://pkg.go.dev/unsafe#Pointer> state:

(1) Conversion of a *T1 to Pointer to *T2.
> Provided that T2 is no larger than T1 and that the two share an equivalent
> memory layout, this conversion allows reinterpreting data of one type as
> data of another type.


Which doesn't apply here, as A is larger than int. I couldn't find any
other rules that seemed relevant. That would seem to imply that above code
is not safe. It would seem to imply that if I want to do something like
that, I have to keep an actual *A alive separately, from F.

Another case where this seems relevant is unsafe.Slice. e.g. is this safe?

func F() *int {
    a := make([]int, 42)
    return &a[0]
}
func G() {
    p := F()
    s := unsafe.Slice(p, 42)
    fmt.Println(s)
}

I can't find any rules at all, about whether or not this is allowed. If it
isn't, I'm left wondering what unsafe.Slice is meant for.

I was wondering about this because I considered using
type slice[T any] struct{
    ptr *T
    len int
    cap int
}
as a map key (prompted by another thread) and couldn't figure out whether
that's actually safe.

As far as I know, `gc` *currently* works fine with this and treats any
pointer into an object as keeping the entire object alive. But could a
theoretical moving GC in the future see that only the first field of a
struct, or only the first element of an array is pointed to and decide to
save memory by shrinking the space allocated? Even worse, could an
implementation decide that only the first field/element is used in the
`return` and just not allocate the rest of the struct/slice?

-- 
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/CAEkBMfGC4Eaam8ufn%2BzkfB4OSMJWi8vVbyJbXQ%3DJpHbzA5dX1g%40mail.gmail.com.

Reply via email to