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
Any C function (even void functions) may be called in a multiple assignment context to retrieve both the return value (if any) and the C errno variable as an error
The problem here is that the C errno variable may be set even when there is no error (man 3 errno is very clear about this) but go developers expect the error return value to be nil when there is no error.
I know google/gopacket#147 was caused by this invalid expectation. I guess there are other bugs laying around for this same reason. When investigating that bug, I decided to open a PR in gopacket because cgo was behaving as specified.
Thinking again about it, I’m now wondering whether the cgo spec is how we want it.
An obvious issue is that it will be hard for cgo to know whether a C function returned an error (in which case errno should be read and translated into a go error) or was successful (in which case we would like the go error to be nil no matter what the errno value is). I believe C functions usually report an error by returning -1 or NULL. But as far as I know, it is the caller’s responsibility to check the specific manual for the function they call, see how it reports error and take appropriate action. Something a generic tool like cgo cannot do.
So maybe the only thing that can be done about this wrong expectation is to warn go developers against it in the cgo documentation. In any case, I believe it is worth opening this discussion.
The text was updated successfully, but these errors were encountered:
I don't see how we can change the existing cgo behavior. Existing code may be depending on it. And, as you say, there is no reasonable way that cgo can determine whether an arbitrary C function has succeeded or not.
So I think that all we can do here is documentation. Taking this out of the proposal process.
In general the cgo approach follows C language rules: only check the error if the function fails. In C the error is checked by looking at the errno variable. With cgo the error is checked by looking at the error result.
ianlancetaylor
changed the title
proposal: cmd/cgo: Retrieve errno only in case of error
cmd/cgo: document that code should only examine errno in case of error
Oct 10, 2023
Existing code may be depending on [the existing cgo behavior].
That would be weird. The current cgo behavior is to return errno after a successful call. But since the content of errno is unspecified in this case, the current cgo behavior is effectively unspecified. Changing the spec to say it will return a nil error after a successful call would only break the current contract in the edge case of a non-standard C function that provides guarantees regarding errno content in case of success.
In general the cgo approach follows C language rules
I know. My whole point is that go developers expect go language rules, rather than C language rules. I believe the job of a bridge like cgo is precisely to translate the source behavior (in this case, C) into the target behavior (in this case, go).
This being said, while I had a slight hope that someone with a better C knowledge than myself would provide a generic mean to detect whether a function failed, as far as I know this is just not possible. So no matter what we think cgo should do, documenting the current behavior is probably our only option.
The cgo documentation states:
The problem here is that the C
errno
variable may be set even when there is no error (man 3 errno
is very clear about this) but go developers expect the error return value to benil
when there is no error.I know google/gopacket#147 was caused by this invalid expectation. I guess there are other bugs laying around for this same reason. When investigating that bug, I decided to open a PR in gopacket because cgo was behaving as specified.
Thinking again about it, I’m now wondering whether the cgo spec is how we want it.
An obvious issue is that it will be hard for cgo to know whether a C function returned an error (in which case
errno
should be read and translated into a go error) or was successful (in which case we would like the go error to benil
no matter what theerrno
value is). I believe C functions usually report an error by returning -1 or NULL. But as far as I know, it is the caller’s responsibility to check the specific manual for the function they call, see how it reports error and take appropriate action. Something a generic tool like cgo cannot do.So maybe the only thing that can be done about this wrong expectation is to warn go developers against it in the cgo documentation. In any case, I believe it is worth opening this discussion.
The text was updated successfully, but these errors were encountered: