-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
spec: clarify the semantics of &p.Field when p is nil #4238
Labels
Milestone
Comments
I suggest that the underlying question is: given a nil pointer p to a struct type. - Must the expression &p.Field cause a runtime-panic? - If it is legal, is &p.Field a nil pointer to the type of p.Field? - What about &*p (which is legal and equal to p currently) ? My understanding of the current spec is that the answers to these questions are unspecified. |
- Must the expression &p.Field cause a runtime-panic? not necessarily, because there are instances in which that might not be a problem, such as unsafe.Sizeof(&p.Field) - If it is legal, is &p.Field a nil pointer to the type of p.Field? no, because if the field offset is 4, &p.Field is 4 if p is nil. - What about &*p (which is legal and equal to p currently) ? not sure Perhaps the resolution is to clarify the meaning around indirection of nil pointers. Labels changed: added priority-soon, removed priority-triage. Status changed to Accepted. |
- x := &*p This never fails. The & operator computes the address of an expression. Computing the address of an expression does not require evaluating it, so *p is never evaluated in this case. &*p is always just 'p'. - x := &p.Field This usually does not fail, for the same reason. However, there is a wrinkle. If you had var p = (*T)(nil) for type T struct { F0 byte F1 byte F2 byte ... F1000000 byte } then it is fine to make &p.F2 be pointer value 2, since dereferencing it later will crash. However, as the field offsets get bigger, eventually you cross into actual memory values, and you cannot let them through. So right now once you get that far (in the gc compiler I believe the limit is F4096) x := &p.F4096 will panic rather than return a pointer you could use without causing a trap. It would be unfortunate to need to talk about this in the spec. If we want to avoid the panic, the only other option is to reuse another pointer, like 0 or 1, but that would produce the perhaps odd result that &p.F1 == &p.F4096 or maybe &p.F0 == &p.F4096 or &p.F4096 == nil. On the other hand it might already be considered odd that &p.F0 == nil. The same is true for array types, of course. |
I might be sufficient to explicitly state that the & operators does not require evaluation of it's operand (in the http://tip.golang.org/ref/spec#Address_operators section). This solves &*p and &p.Field for "small" field offsets. The &p.F4096 panic is an implementation issue: For instance, one could conceive an implementation where pointers are always a pair (base pointer, offset) and the this panic could be avoided (at the cost of a more expensive implementation). I'd be ok with a short sentence mentioning an implementation restriction. |
See also good discussion in issue #4464. |
Issue #4464 has been merged into this issue. |
golang.org/s/go12nil. We've decided to do this. Robert, do you have bandwidth for the spec changes? Owner changed to @griesemer. |
Spec change in https://golang.org/cl/12964043 Status changed to Fixed. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
The text was updated successfully, but these errors were encountered: