Are the two unsafe uses safe?

144 views
Skip to first unread message

tapi...@gmail.com

unread,
Feb 27, 2021, 11:00:26 PM2/27/21
to golang-nuts
1.

func String2ByteSlice(s string) []byte {
    return (*[^uint(0) >> 1]byte)(unsafe.Pointer(&s))[:len(s):len(s)]
}

2.

func String2ByteSlice(s string) []byte {
    return *(*[]byte)(unsafe.Pointer(&struct{string; int}{s, len(s)}))
}

tapi...@gmail.com

unread,
Feb 28, 2021, 3:09:10 AM2/28/21
to golang-nuts
Sorry, the first one will get a "type [9223372036854775807]byte larger than address space" error.
The following code will get the same error

    var x *[^uint(0) >> 1]byte

Is this error essential?

Axel Wagner

unread,
Feb 28, 2021, 4:48:00 AM2/28/21
to tapi...@gmail.com, golang-nuts
On Sun, Feb 28, 2021 at 9:09 AM tapi...@gmail.com <tapi...@gmail.com> wrote:
Is this error essential?

Yes. You need to be able to do arithmetic on addresses to use an array, but for that they need to have a known type and size. By exceeding the address space, you are creating a type that the compiler can't work with - that is, it can't allow you to create that type, because it wouldn't know how to use it.
 

On Saturday, February 27, 2021 at 11:00:26 PM UTC-5 tapi...@gmail.com wrote:
1.

func String2ByteSlice(s string) []byte {
    return (*[^uint(0) >> 1]byte)(unsafe.Pointer(&s))[:len(s):len(s)]
}

2.

func String2ByteSlice(s string) []byte {
    return *(*[]byte)(unsafe.Pointer(&struct{string; int}{s, len(s)}))
}

--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/411f0d80-eb3c-4737-94cf-1f4dd73e1678n%40googlegroups.com.

Ian Lance Taylor

unread,
Feb 28, 2021, 8:29:51 AM2/28/21
to tapi...@gmail.com, golang-nuts
On Sat, Feb 27, 2021 at 8:00 PM tapi...@gmail.com <tapi...@gmail.com> wrote:
>
> 1.
>
> func String2ByteSlice(s string) []byte {
> return (*[^uint(0) >> 1]byte)(unsafe.Pointer(&s))[:len(s):len(s)]
> }

This doesn't do what you probably want, as &s is not the address of
the bytes in the string.


> 2.
>
> func String2ByteSlice(s string) []byte {
> return *(*[]byte)(unsafe.Pointer(&struct{string; int}{s, len(s)}))
> }

This is more likely to work but it's not safe.

Ian

tapi...@gmail.com

unread,
Feb 28, 2021, 10:51:38 AM2/28/21
to golang-nuts
On Sunday, February 28, 2021 at 8:29:51 AM UTC-5 Ian Lance Taylor wrote:
On Sat, Feb 27, 2021 at 8:00 PM tapi...@gmail.com <tapi...@gmail.com> wrote:
>
> 1.
>
> func String2ByteSlice(s string) []byte {
> return (*[^uint(0) >> 1]byte)(unsafe.Pointer(&s))[:len(s):len(s)]
> }

This doesn't do what you probably want, as &s is not the address of
the bytes in the string.
 
Aha, I forgot this point.


> 2.
>
> func String2ByteSlice(s string) []byte {
> return *(*[]byte)(unsafe.Pointer(&struct{string; int}{s, len(s)}))
> }

This is more likely to work but it's not safe.

Why? For slice field order is undefined?
 

Ian

Ian Lance Taylor

unread,
Feb 28, 2021, 1:47:19 PM2/28/21
to tapi...@gmail.com, golang-nuts
Yes: the language does not define what a slice looks like in memory.
It may be implemented differently by different implementations,
including by different releases of the same implementation.

Ian
Reply all
Reply to author
Forward
0 new messages