Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/cgo: C.malloc does not support comma error return values #16309

Closed
catalase opened this issue Jul 9, 2016 · 21 comments

Comments

@catalase
Copy link

commented Jul 9, 2016

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?
$ go version
go version go1.6.2 windows/amd64
  1. What operating system and processor architecture are you using (go env)?
$ go env
set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\Administrator\Go
set GORACE=
set GOROOT=C:\go
set GOTOOLDIR=C:\go\pkg\tool\windows_amd64
set GO15VENDOREXPERIMENT=1
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
  1. What did you do?

I ran cgom.go whose source is at https://play.golang.org/p/lFkVjkjn5W

  1. What did you expect to see?

In cgo manual (https://golang.org/cmd/cgo/), the manual states that

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 (use _ to skip the result value if the function returns void). For example:

I think C.malloc is C function. And Any C function may be called in a multiple assignemt context. Therefore, C.malloc should be called in a multiple assignment.

The idea was correct only if compilation would be successful.

  1. What did you see instead?
$ go run cgom.go
# command-line-arguments
.\cgom.go:22:12: no two-result form for C.malloc

Unfortunately, reality is not. C.malloc cannot be used in that way, even though free function can be used in that way.

C.malloc function seems not to be part of a set of C functions, because contraposition of "Any C function may be called in a multiple assignment context" is "if a function may not be called in a multiple context, then the function is not C function".

This contradicts usual idea that malloc should be C function. Go override some of special functions as malloc, etc. But these functions do not act like C functions.

@catalase catalase changed the title C.malloc is not a function allowing multiple return. C.malloc is not a function allowing multiple returns. Jul 9, 2016

@catalase catalase changed the title C.malloc is not a function allowing multiple returns. C: C.malloc is not a function allowing multiple returns. Jul 9, 2016

@josharian josharian changed the title C: C.malloc is not a function allowing multiple returns. cmd/cgo: C.malloc does not support comma error return values Jul 9, 2016

@josharian

This comment has been minimized.

Copy link
Contributor

commented Jul 9, 2016

@ianlancetaylor ianlancetaylor added this to the Go1.8 milestone Jul 10, 2016

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Jul 10, 2016

I think the likely resolution of this is to say that C.malloc is an exception.

Is there any reason that it is important to get an errno result from C.malloc? It has no defined errno results anyhow, and in practice the only one it ever returns is ENOMEM.

@catalase

This comment has been minimized.

Copy link
Author

commented Jul 10, 2016

@ianlancetaylor If C.malloc changes as an exception, https://golang.org/cmd/cgo/ should be modified to specify that C.malloc is an exception.

I'm think differently. Whether C.malloc may support comma error return or not has something with consistency. There are a lot of C functions that has no defined or uesless errno such as C.malloc, C.free, .... It is consistency to support comma error return regardless of advantage of that errno. I think unnecessary consistency is a consistency for consistency.

@jessfraz

This comment has been minimized.

Copy link
Contributor

commented Aug 16, 2016

I think C.malloc should be an exception, if that's ok I can make a patch to the docs.

@sh4m1l65

This comment has been minimized.

Copy link

commented Sep 3, 2016

Please explain the rationale for excepting C.malloc from the documented CGO multi-valued return behavior. errno==ENOMEM is part of how malloc(3) is documented to signal failure. The multi-valued return makes the Go idiom of checking for err != nil possible:

cptr, err := C.malloc(C.sizeof_struct_foo)
if err != nil {

return nil, fmt.Errorf("allocating memory exempt from GC: %v", err)

}
// ... use cptr

If there is an overriding concern, I don't yet understand it. If possible, please explain it.

@minux

This comment has been minimized.

Copy link
Member

commented Sep 4, 2016

@aclements

This comment has been minimized.

Copy link
Member

commented Oct 5, 2016

While the case is certainly obscure, it seems reasonable to me to make C.malloc consistent with other functions and keep the documentation simple. Arguably, the obscurity of the case even supports keeping the documentation simple.

Is there some technical reason why this isn't easy to fix?

@jessfraz

This comment has been minimized.

Copy link
Contributor

commented Oct 5, 2016

This would be a breaking change to the API

@w7tek

This comment has been minimized.

Copy link

commented Oct 5, 2016

How is that a breaking change? It is already the case that Cgo code may call C functions with either a single or a single plus error result. Code that is already written to not "request" the error result from C.malloc will continue to work just the same as other code for C language functions that don't care to pick up the error result. Code that currently won't work if written as documented, would become compilable.

Please explain how this is an incompatible change?

@quentinmit

This comment has been minimized.

Copy link
Contributor

commented Oct 5, 2016

Supporting code that previously didn't compile, without changing behavior for code that did previously compile, doesn't seem like a breaking change to me.

@aclements

This comment has been minimized.

Copy link
Member

commented Oct 5, 2016

This would be a breaking change to the API

How so? Currently the only way to call C.malloc is with zero or one return values. I don't think anyone's proposing changing the behavior in this case (including the panic behavior). This just adds the possibility to call it with two return values. The only oddity would be that, presumably, we would still want it to panic in the zero or one case, and not panic in the two case. This is different from other C functions, but not without precedent in the language (e.g., one- versus two-assignment type assertions).

@jessfraz

This comment has been minimized.

Copy link
Contributor

commented Oct 5, 2016

ok calm yourself I misunderstood apologies

@w7tek

This comment has been minimized.

Copy link

commented Oct 5, 2016

Ok. That's understandable. If it were true, the "breaks API compatibility" card would clearly trump the desire to avoid gratuitous one-off, contrary-to-documented behavior. That's why the (mistaken?) claim of incompatible change comes across as such a big deal.

@w7tek

This comment has been minimized.

Copy link

commented Oct 5, 2016

and when I say "gratuitous one-off, contrary-to-documented" behavior, I would be glad to be proved wrong. I just don't think the conversation thus far on this issue has demonstrated that it's not a gratuitous deviation from documented behavior. Maybe it's the search for that answer that will bring about a satisfactory closing of this issue. Or, maybe it is what I think it is, and should be fixed to support calling the same way other Cgo functions can be called.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Oct 6, 2016

I'm fine with handling an errno return from C.malloc. It seems pointless to me but I'll review the CL if someone wants to do the work.

@w7tek

This comment has been minimized.

Copy link

commented Oct 7, 2016

@ianlancetaylor help? I don't recognize the CL initials. I would be glad to roll up my sleeves and dig into this, because gratuitous inconsistency consistently bugs me. I'm reading https://golang.org/doc/contribute.html now as a first step.

@bradfitz

This comment has been minimized.

Copy link
Member

commented Oct 7, 2016

CL = "change list". Think "PR" (Pull request) or "patch".

You found the right contributing docs.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Oct 21, 2016

C.malloc is special because we guarantee it can never fail. I will send a CL documenting this.

@gopherbot

This comment has been minimized.

Copy link

commented Oct 24, 2016

CL https://golang.org/cl/31811 mentions this issue.

@gopherbot gopherbot closed this in 2a3db5c Oct 24, 2016

@sh4m1l65

This comment has been minimized.

Copy link

commented Oct 31, 2016

@rsc @ianlancetaylor thank you both for this. The CL https://golang.org/cl/31811 LGTM assuming https://golang.org/cl/31768 also is accepted at the same release.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Nov 1, 2016

@sh4m1l65 Both changes will be in the Go 1.8 release.

@golang golang locked and limited conversation to collaborators Nov 1, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
You can’t perform that action at this time.