-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/cgo: permits reference to non-existent struct #19487
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
Also applies to non-existent unions, but not enums. |
CL https://golang.org/cl/44774 mentions this issue. |
Once we refer C.struct_undefined, cgo emits I think one solid solution here is rejecting all incomplete types. That said, those changes brake some backward compatibility. So it may be controversial. I sent my CL, but please feel free to reject it :) |
Not just backward compatibility, but also compatibility with a wide variety of C APIs. It's fine to pass around pointers to an incomplete struct type: the problem occurs when you're trying to actually instantiate a struct of that type. |
But perhaps that implies that Instead of doing the equivalent of type struct_x struct { _ [0]byte } perhaps we could emit a Go struct type for type ptr_struct_x struct { _ unsafe.Pointer } Assuming that the Go compiler generates correct code to copy structs with blank-identifier fields, that would allow Go code to copy values of type |
The CL only rejects direct use of incomplete type in Go. It doesn't prohibit indirect use of incomplete type.
will produce
into _cgo_gotypes.go. This is the same behavior as current code. I confirmed that opaque pointer pattern is still working. I roughly understand that 'incomplete type' means that the type cannot determine its own size at compile time. All pointers have the exact size (e.g. 8 byte on amd64), so 'pointer to incomplete type' aren't 'incomplete type' themselves.
I'm not correctly sure what are you suggesting here. But if you are suggesting
I agree with you. Current code have already done the similar decision for void* . It is the generalized decision of that. |
If I'm reading it correctly, it would break
No, I'm suggesting that we not require the package main
/*
#cgo LDFLAGS: -L${SRCDIR} opaque.dylib
#include "opaque.h"
*/
import "C"
func main() {
p := C.createPerson(10)
C.printPerson(p)
C.destroyPerson(p)
} opaque.h: typedef struct Person Person;
Person* createPerson(int age);
void destroyPerson(Person* p);
void printPerson(Person* p); In the cgo-translated code, type _Ctype_ptr_Person struct { _ unsafe.Pointer } That way, Go code could still copy and assign The one caveat to that approach is that we would also have to translate: var p *C.person = nil to var p _Ctype_ptr_Person = _Ctype_ptr_Person{} since |
I understand I was wrong. Thank you.
I cannot understand why do you need to wrap unsafe.Pointer in struct. |
Anyway, I have no idea to solve this problem now. |
Yes, but it allows for some potentially-surprising conversions (see #20171). |
Thinking about this further, the |
I don't see that there's an obvious fix here. The current behavior might be the best of the possible choices. In any event, not for Go 1.10. |
This code compiles and runs:
It prints
{}
. That makes no sense. There is no typeX
here. It should give an error somewhere.The text was updated successfully, but these errors were encountered: