FAQ
Hello,

Is there a safe(r) way of checking whether two slices point to the
same underlying array than going through unsafe.Pointer and casting
the result to reflect.SliceHeader?

I have a solution that works, but I'm not sure how to interpret the
SliceHeader warning: "It cannot be used safely or portably." Is that
in reference to different architectures, Go compilers, Go versions, or
all of the above?

A demo of my solution is here, but you have to run it locally due to
the unsafe import:

http://play.golang.org/p/gwJtKK__gG

One function tells you if two byte slices share the same array.
Another returns the overlapping region, if there is one.

- Max

--

Search Discussions

  • Peter S at Oct 15, 2012 at 3:38 pm
    From http://golang.org/src/pkg/math/big/nat.go#L340

    // alias returns true if x and y share the same base array.
    func alias(x, y nat) bool {
    return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] ==
    &y[0:cap(y)][cap(y)-1]
    }

    In this example "nat" is a slice type, the same approach should also work
    with []byte or other slice types.

    HTH,

    Peter
    On Mon, Oct 15, 2012 at 11:58 PM, Maxim Khitrov wrote:

    Hello,

    Is there a safe(r) way of checking whether two slices point to the
    same underlying array than going through unsafe.Pointer and casting
    the result to reflect.SliceHeader?

    I have a solution that works, but I'm not sure how to interpret the
    SliceHeader warning: "It cannot be used safely or portably." Is that
    in reference to different architectures, Go compilers, Go versions, or
    all of the above?

    A demo of my solution is here, but you have to run it locally due to
    the unsafe import:

    http://play.golang.org/p/gwJtKK__gG

    One function tells you if two byte slices share the same array.
    Another returns the overlapping region, if there is one.

    - Max

    --

    --
  • Dumitru Ungureanu at Oct 15, 2012 at 3:42 pm
    So x is []Word.
    What this is saying: &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1] ?

    Basically, the general logic is that two slices x and y overlap if at least
    one slice element from x has the same memory address with one slice element
    from y... but I'm kind of lost to that syntax.

    --
  • Maxim Khitrov at Oct 15, 2012 at 3:53 pm
    The two slices overlap if they both end at the same address. Once a
    slice is created, you can move its starting address forward, but never
    beyond start + capacity, which is a fixed value for any slice. That
    syntax reslices x and y to their full capacity and takes the address
    of the last element.

    - Max
    On Mon, Oct 15, 2012 at 11:34 AM, Dumitru Ungureanu wrote:
    So x is []Word.
    What this is saying: &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1] ?

    Basically, the general logic is that two slices x and y overlap if at least
    one slice element from x has the same memory address with one slice element
    from y... but I'm kind of lost to that syntax.
    --
  • Dumitru Ungureanu at Oct 15, 2012 at 4:44 pm

    On Monday, October 15, 2012 6:45:44 PM UTC+3, Maxim Khitrov wrote:

    The two slices overlap if they both end at the same address. Once a
    slice is created, you can move its starting address forward, but never
    beyond start + capacity, which is a fixed value for any slice. That
    syntax *reslices x and y to their full capacity* and takes the address
    of the last element.

    - Max
    The *A-HA* moment! Thank you.

    --
  • Roger peppe at Oct 15, 2012 at 4:33 pm

    On 15 October 2012 16:34, Dumitru Ungureanu wrote:
    So x is []Word.
    What this is saying: &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1] ?

    Basically, the general logic is that two slices x and y overlap if at least
    one slice element from x has the same memory address with one slice element
    from y... but I'm kind of lost to that syntax.
    It's testing whether that very last element of each of the underlying arrays
    has the same pointer. This is a sufficient test because a slice always
    remembers its capacity, so you cannot make the last element in the underlying
    array unavailable.

    --
  • Maxim Khitrov at Oct 15, 2012 at 4:37 pm
    Much better, thanks! Here's the updated version of my code that no
    longer requires unsafe and reflect:

    http://play.golang.org/p/OXSfGvkC0y

    Needs more testing, but I think I got the math right.

    - Max
    On Mon, Oct 15, 2012 at 11:12 AM, Peter S wrote:
    From http://golang.org/src/pkg/math/big/nat.go#L340

    // alias returns true if x and y share the same base array.
    func alias(x, y nat) bool {
    return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] ==
    &y[0:cap(y)][cap(y)-1]
    }

    In this example "nat" is a slice type, the same approach should also work
    with []byte or other slice types.

    HTH,

    Peter
    On Mon, Oct 15, 2012 at 11:58 PM, Maxim Khitrov wrote:

    Hello,

    Is there a safe(r) way of checking whether two slices point to the
    same underlying array than going through unsafe.Pointer and casting
    the result to reflect.SliceHeader?

    I have a solution that works, but I'm not sure how to interpret the
    SliceHeader warning: "It cannot be used safely or portably." Is that
    in reference to different architectures, Go compilers, Go versions, or
    all of the above?

    A demo of my solution is here, but you have to run it locally due to
    the unsafe import:

    http://play.golang.org/p/gwJtKK__gG

    One function tells you if two byte slices share the same array.
    Another returns the overlapping region, if there is one.

    - Max

    --
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedOct 15, '12 at 2:58p
activeOct 15, '12 at 4:44p
posts7
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase