Go version
1.22.5 (this is from pkg.go.dev
)
Output of go env
in your module/workspace:
N/A as I discovered this problem viewing the online docs.
What did you do?
Looked at the documentation for unsafe.String
What did you see happen?
The documentation for unsafe.String
states (correctly):
Since Go strings are immutable, the bytes passed to String must not be modified afterwards.
However, it does not state for how long this holds. Is it sufficient for the bytes to remain valid until there are no more source-level references to the String, or is the actual requirement stricter?
To use a concrete example: Suppose I get a pointer from C’s malloc
and use unsafe.String
to obtain a string pointing to its contents. Once I am done with the string I free the pointer with C’s free
. Is this safe?
What did you expect to see?
An answer to this question.
Comment From: randall77
Is it sufficient for the bytes to remain valid until there are no more source-level references to the String
Yes, that is enough.
The tricky part documentation-wise is how to write that. "source-level references" isn't defined anywhere. "until the string goes dead"? Also not defined anywhere. Suggestions welcome, but I don't see an easy way to specify this without going down a rathole.
Comment From: DemiMarie
Is it sufficient for the bytes to remain valid until there are no more source-level references to the String
Yes, that is enough.
Good to know. Is it sufficient for the bytes to remain valid until the string is no longer used, or could a this cause a crash?
The tricky part documentation-wise is how to write that. "source-level references" isn't defined anywhere. "until the string goes dead"? Also not defined anywhere. Suggestions welcome, but I don't see an easy way to specify this without going down a rathole.
I think some examples would be best.
Comment From: randall77
Is it sufficient for the bytes to remain valid until the string is no longer used, or could a this cause a crash?
Mostly ok, but I think there are difficult corners for maps. "No longer used" will also be hard to define in that case. What if it is a key in a map[string]int
, but its entry is never accessed? Is that a "use"? (It needs to be, otherwise bad things will happen.) What if the map itself isn't used? Maybe that would be ok, but that precludes us ever re-hashing maps under the covers (which we might need to do if we ever have a moving gc).
Comment From: gopherbot
Change https://go.dev/cl/596955 mentions this issue: unsafe: clarify when String bytes can be modified