-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/cgo: never generate Go fields for zero-sized C fields #20275
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
Comments
I was able to reproduce with If we change the array to a pointer we get |
This is happening because the implicit padding added by these lines (in
is adding a new trailing field and thus breaking the check of whether the actual trailing field has zero size. This does mean that the trailing zero-sized field is going to work in this case, but it would minimize confusion to drop the trailing field in this case as well. Actually, we don't want to drop it, we want to rename it to |
I'm not sure that we should even rename it. We should convert it to a zero-sized Go array so that it can still be addressed. There's nothing obviously wrong with this program, for example, assuming that package main
/*
struct foo {
int x;
char padding;
char y[];
};
extern struct foo* foo_create();
extern void foo_destroy(struct foo*);
*/
import "C"
import (
"fmt"
"unsafe"
)
func main() {
y := C.foo_create()
defer C.foo_destroy(y)
c := (*C.char)((unsafe.Pointer)(&y.y))
fmt.Println(*c)
} |
@bcmills Offhand I don't see how to do that while still preserving the size of the struct as seen in Go as being the same as the size as seen in C. That seems like a difficult property to lose. See https://golang.org/cl/12864 . |
I can see how to solve it with a fairly minimal language change, but not without one. The language change would be to add a distinguished zero-size type ( type struct_foo struct{
x C.int
padding C.char
y unsafe.Void
} and the |
I don't want to change cgo this late in the cycle but I would be OK for Go 1.11 with never making that field accessible. That will end the inconsistency. We should not make language changes to Go just for this awful detail of C. |
Similar to @bcmills 's idea, we can use |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?tested with 1.7.5 and 1.8.1
What operating system and processor architecture are you using (
go env
)?linux/amd64
What did you do?
What did you expect to see?
Y.y undefined (type C.struct_foo has no field or method y)
(because Y.y is a zero-length field and Go code cannot refer to these fields)
What did you see instead?
Compiles and prints:
I've checked that it's dependent on memory alignment. If the
padding
field is removed from struct foo, generated cgo type doesn't have they
field. With the padding, the field is included.The text was updated successfully, but these errors were encountered: