Question about safe unsafe.Pointer conversion rules

69 views
Skip to first unread message

Iskander Sharipov

unread,
Jun 19, 2020, 3:04:01 PM6/19/20
to golang-nuts
Hello!


type Func struct {
        opaque struct{} // unexported field to disallow conversions
}

func (f *Func) raw() *_func {
        return (*_func)(unsafe.Pointer(f))
}

An empty struct Func (T1) is converted to a non-zero struct _func (T2).

From the unsafe.Pointer documentation (https://golang.org/pkg/unsafe/#Pointer):

> T1->T2 conversion is safe if T2 is no larger than T1 ... (shortened for clarity)

I'm guessing that documentation probably meant "allocation size", not the "static type size"?
T1 pointer can be obtained from the T2 allocation, so it's allocation size can be different from the unsafe.Sizeof(T1{}).

Or it could be that runtime can violate that particular rule.

My question: is it same to convert T1<->T2 even if sizeof(T1)<sizeof(T2), but the memory was allocated for the bigger object?

Thank you in advance.



Iskander Sharipov

unread,
Jun 19, 2020, 3:08:01 PM6/19/20
to golang-nuts
s/same/safe/

The question is about whether it's safe to do the same conversion outside of the Go runtime.

Ian Lance Taylor

unread,
Jun 19, 2020, 3:13:49 PM6/19/20
to Iskander Sharipov, golang-nuts
Your last point is correct: the runtime package is allowed to violate
the rules. In this case it is safe because Func values are never
allocated and are never garbage collected. They are always part of
the read-only section of the program itself.

Ian

Iskander Sharipov

unread,
Jun 19, 2020, 3:29:07 PM6/19/20
to golang-nuts
I used this to write something like a runtime in Go.


I was wondering whether this code can break at some point.

On Friday, June 19, 2020 at 10:04:01 PM UTC+3, Iskander Sharipov wrote:

Ian Lance Taylor

unread,
Jun 19, 2020, 4:32:19 PM6/19/20
to Iskander Sharipov, golang-nuts
On Fri, Jun 19, 2020 at 12:29 PM Iskander Sharipov <quas...@gmail.com> wrote:
>
> I used this to write something like a runtime in Go.
>
> https://play.golang.org/p/6jYw5L3fy0B
>
> I was wondering whether this code can break at some point.

I don't see any way that that code could break, but I agree that it
does not follow the rules, so it is not guaranteed to always work.

Ian



> On Friday, June 19, 2020 at 10:04:01 PM UTC+3, Iskander Sharipov wrote:
>>
>> Hello!
>>
>> https://golang.org/src/runtime/symtab.go?s=7594:7745#L244
>>
>> type Func struct {
>>
>> opaque struct{} // unexported field to disallow conversions
>>
>> }
>>
>>
>> func (f *Func) raw() *_func {
>>
>> return (*_func)(unsafe.Pointer(f))
>>
>> }
>>
>>
>> An empty struct Func (T1) is converted to a non-zero struct _func (T2).
>>
>> From the unsafe.Pointer documentation (https://golang.org/pkg/unsafe/#Pointer):
>>
>> > T1->T2 conversion is safe if T2 is no larger than T1 ... (shortened for clarity)
>>
>> I'm guessing that documentation probably meant "allocation size", not the "static type size"?
>> T1 pointer can be obtained from the T2 allocation, so it's allocation size can be different from the unsafe.Sizeof(T1{}).
>>
>> Or it could be that runtime can violate that particular rule.
>>
>> My question: is it same to convert T1<->T2 even if sizeof(T1)<sizeof(T2), but the memory was allocated for the bigger object?
>>
>> Thank you in advance.
>>
>>
>>
> --
> 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/fbeb324a-be55-4673-86a9-f6dc1046b0bco%40googlegroups.com.

Iskander Sharipov

unread,
Jun 19, 2020, 6:46:49 PM6/19/20
to golang-nuts
Many thanks Ian!
> To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages