Dear golang nuts,
I was trying to gain a better understanding of how cgo works internally,
when I stumbled upon this implementation detail:
https://github.com/golang/go/blob/8db131082d08e497fd8e9383d0ff7715e1bef478/src/runtime/cgocall.go#L628
```
case kindStruct:
st := (*structtype)(unsafe.Pointer(t))
if !indir {
if len(st.Fields) != 1 {
throw("can't happen")
}
cgoCheckArg(st.Fields[0].Typ, p,
st.Fields[0].Typ.Kind_&kindDirectIface == 0, top, msg)
return
}
```
This is inside the function where an argument passed to C is checked for
whether it is/contains a pointer to memory containing unpinned go pointers.
In this specific switch-case, the type of the object being checked is a
struct (t.Kind_ is kindStruct). Furthermore,
this is the !indir-branch, which indicates that p is actually the struct
itself and not a pointer to it, i.e. the entire struct is stored within p,
and the struct has only one field. My question is specifically about the
the recursive call
`cgoCheckArg(st.Fields[0].Typ, p, st.Fields[0].Typ.Kind_&kindDirectIface ==
0, top, msg)`
I don't understand why it should be possible here for the third ("indir")
argument to be true? What would be a case in which this being set to true
is not contradictory?
When the structs' field's type is not a kindDirectIface, the recursive call
is performed with arguments (st.Fields[0].Typ, p, true, ...). That means,
we are indicating that p is a *pointer to* a value of type
st.Fields[0].Typ. But in the current, enclosing call of the function, we
are in the "!indir"-branch, meaning that p is *exactly* the struct value,
which is exactly the value of its first (and only) field. So we know p is
semantically of type st.Fields[0].Typ, not of type "pointer to
st.Fields[0].Typ". Isn't this a contradiction? How can p be both a pointer
to a st.Fields[0].Typ and be equal to a struct whose only field has type
st.Fields[0].Typ?
The only explanation I can see is that either
st.Fields[0].Typ.Kind_&kindDirectIface == 0 is (almost) always false in
practice, and this line catches a very special case, or that there are
cases in which st.Fields[0].Typ contains the value "type Bar" even though
the actual field's value is semantically "pointer to Bar" and not "Bar".
I apologize for the admittedly extremely specific question. I would really
appreciate if someone who is knowledgable about the internals could have a
look at this.
Thanks a lot for your time.
Best Regards,
JC
--
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/7c63b691-a37d-46ae-8843-3d2177ecd3e1n%40googlegroups.com.