You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What operating system and processor architecture are you using (go env)?
N/A
What did you do?
The proposed #cgo noescape pragma (#56378) is documented to say:
When passing a Go pointer to a C function the compiler normally ensures
that the Go object lives on the heap. If the C function does not keep
a copy of the Go pointer, and never passes the Go pointer back to Go code,
then this is unnecessary. The #cgo noescape directive may be used to tell
the compiler that no Go pointers escape via the named C function.
If the noescape directive is used and the C function does not handle the
pointer safely, the program may crash or see memory corruption.
However, the property "If the C function does not keep a copy of the Go pointer" seems guaranteed for non-pinned memory by the rule that
C code may not keep a copy of a Go pointer after the call returns,
unless the memory it points to is pinned with [runtime.Pinner]
So my question is: what can "#cgo noescape" promise that is not already promised?
One answer may be "pinned objects may be retained by C". But then why not force objects passed to runtime.Pinner to the heap?
Another answer may be "Go objects may escape through callbacks to from C to Go", then that seems entirely covered by the "#cgo nocallback" pragma.
In summary, "#cgo noescape" seems to add no useful information.
What did you expect to see?
No "#cgo noescape" pragma, or clearer documentation what "#cgo noescape" promises that is not already promised.
What did you see instead?
A seemingly redundant "#cgo noescape" pragma.
The text was updated successfully, but these errors were encountered:
@eliasnaur I see a third case, C can return a Go pointer back to go.
Then the pointer does escape but isn't retained by C.
The escape analysis is able to model this properly when reading go code, but the noescape pragmas are way under capable compared to the level of detail the escape analysis read code.
Yes, I think (if my memory serves) the issue has to do with Go -> C -> Go cases. Doesn't happen very often, but it is something we support. Perhaps the documentation could be clarified/enhanced.
@eliasnaur#cgo noescape is disabled in 1.22, and will enable in 1.23, so, there is no much doc about it.
For such a Go function:
func get() uint64 {
var value C.uint64_t
C.GetIntegerValue(&value)
return uint64(value)
}
without #cgo noescape , value will always escape to heap.
after adding #cgo noescape GetIntegerValue, value will be on stack.
it's a normal optimization for cgo.
And pin is another thing.
we can also say the Go pointer &value is pinned, when it's on the stack, since it won't move before C entering Go again.
Yes, I think (if my memory serves) the issue has to do with Go -> C -> Go cases. Doesn't happen very often, but it is something we support. Perhaps the documentation could be clarified/enhanced.
Thank you. I missed that a returned value is a violation of "never passes the Go pointer back to Go code".
Go version
go1.22rc1
What operating system and processor architecture are you using (
go env
)?What did you do?
The proposed
#cgo noescape
pragma (#56378) is documented to say:However, the property "If the C function does not keep a copy of the Go pointer" seems guaranteed for non-pinned memory by the rule that
So my question is: what can "#cgo noescape" promise that is not already promised?
One answer may be "pinned objects may be retained by C". But then why not force objects passed to runtime.Pinner to the heap?
Another answer may be "Go objects may escape through callbacks to from C to Go", then that seems entirely covered by the "#cgo nocallback" pragma.
In summary, "#cgo noescape" seems to add no useful information.
What did you expect to see?
No "#cgo noescape" pragma, or clearer documentation what "#cgo noescape" promises that is not already promised.
What did you see instead?
A seemingly redundant "#cgo noescape" pragma.
The text was updated successfully, but these errors were encountered: