Go version
1.22.6
Output of go env
in your module/workspace:
N/A
What did you do?
N/A
What did you see happen?
The documentation for cmd/cgo#Passing pointers states that strings and slices always contain Go pointers:
Note that values of some Go types, other than the type's zero value, always include Go pointers. This is true of string, slice, interface, channel, map, and function types.
This seems to imply that the following is UB, as it constructs a slice from a C pointer rather than a Go pointer:
//export processData
func processData(ptr unsafe.Pointer, len C.size_t) {
s := unsafe.Slice((*byte)(ptr), len)
fmt.Println("got data:", string(s))
}
However, discussion on the Gophers Slack suggests that this may actually be perfectly fine, as Go should still know whether a pointer points to memory managed by Go. syscall.Mmap was mentioned as an example of a slice not backed by Go-managed memory.
What did you expect to see?
Accurate information in the Cgo documentation regarding the safety of strings and slices backed by C-managed memory.
In either case, an explicit description of the safety or non-safety of passing a C pointer would be appreciated in the documentation for unsafe.String
and unsafe.Slice
.
As an aside, it would also be good to document any other invariants that must be upheld by the data passed to unsafe.String
, if applicable. In particular, whether the string must be valid UTF-8, and whether it may contain null bytes.
Comment From: gabyhelp
Related Issues and Documentation
- cmd/cgo: pointer check is too aggressive with bytes.Buffer #22788 (closed)
- cmd/cgo: cgo pointer checking panic on address of slice from function call #14210 (closed)
- unsafe: confusing docs about unsafe.String #68300 (closed)
- cmd/cgo: compiler complains about `C.free(*C.char)` but is happy with `defer C.free(*C.char)` #17562 (closed)
- cmd/cgo: false cgo "Go pointer to Go pointer" #18184 (closed)
- Command cgo > Passing pointers
- Command cgo > Passing pointers
- unsafe: document valid uses of `unsafe.Pointer` for non-Go memory #42467 (closed)
- cmd/cgo: panic while checking **unsafe.Pointer in cgo call #13830 (closed)
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: gopherbot
Change https://go.dev/cl/604715 mentions this issue: cmd/cgo: clarify that strings and slices may contain C pointers
Comment From: ianlancetaylor
I committed a patch to clarify the cgo docs.
I don't think that unsafe.String
or unsafe.Slice
are the right place to discuss C pointers.
Go defines strings as a sequence of bytes (for example, https://go.dev/ref/spec#String_types). As such, there are no restrictions on the bytes passed to unsafe.String
. They need not be UTF-8, they may contain NUL.