-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: define that structs are compared field-by-field as listed in source code #8606
Comments
Labels changed: added documentation. Owner changed to @griesemer. Status changed to Accepted. |
@griesemer, @ianlancetaylor, I closed #38676 as a duplicate of this one but it'd be nice to get a decision here for https://go-review.googlesource.com/c/go/+/230207 ("cmd/compile: improve generated eq algs for structs containing interfaces"). |
I'm inclined to say the spec should explicitly say the order of field/element comparison is unspecified, and a struct/array with both unequal and incomparable fields/elements may either compare false or panic. I'd say go ahead with CL 230207. |
I agree with @mdempsky. If we ever decide to implement more struct order of evaluation, this would be another place where we ought to specify the order. |
If we go that route (which I support), and we wanted to prevent people from accidentally relying on short-circuiting behavior, we could generate always-panic implementations in -race mode (or under a new flag). |
I'd also agree with @mdempsky. More generally, a principle I like is to assume that anything that is not explicitly defined by the language spec is in is in fact unspecified even if we don't say so explicitly, and thus should no be relied upon. |
Isn't one of the goals of Go is to reduce unspecified cases as few as possible? |
We want to reduce dependence on unspecified behavior as much as possible. That is not quite the same as saying something is unspecified in the spec. (For instance, map iteration order is not specified, and by making it random, people cannot rely upon some implementation-dependent iteration order.) |
I would not say that it is a goal of Go to reduce unspecified cases as much as possible. I don't think we're opposed to reducing unspecified cases, but it's not a goal. If reducing unspecified cases were a goal we would have exact rules of order of evaluation, exact rules for map iteration, etc. |
I started implementing this and it got complicated and ugly, so I stopped. If folks actively want it, I can try again. Otherwise, I'm going to throw in the hat. |
@griesemer @ianlancetaylor |
The immediate one is it would prevent optimization CLs like 230207, which users seem more likely to benefit from than to be harmed by it. More generally, we reserve the right to make changes in behavior as long as they still conform to the language spec. |
OK, get it. But I think, from general user point view, predicable behaviors would be better. |
Some users want predictable behavior, some users want faster code. We have to make our best guess as to which is most important for each specific case. |
The spec says that structs are equal if all the fields are equal. It also says We could relax the rules and say the panic may or may not happen depending on other struct field values, but if we did that, different implementations would behave differently. Moving code from one system to another might mean a panic appears where it never did before, making people think the new system has a bug. The spec doesn't say what order fields are compared, but it implies that they are all compared. If there are two different interface fields that cause panics in a particular comparison, it doesn't matter much which one happens, but one has to happen (not zero). A compiler that wants to short-circuit field comparisons just has to do all the interfaces before it starts being clever. Moving into proposal process to make sure discussion terminates. |
@rsc The previous title mentioned arrays. Did you intentionally omit that from retitling? I think if we're specifying that structs are compared field-by-field in source order, then arrays should also be compared element-by-element in index order. |
Change https://golang.org/cl/237919 mentions this issue: |
Make sure that if a field comparison might panic, we evaluate (and short circuit if not equal) all previous fields, and don't evaluate any subsequent fields. Add a bunch more tests to the equality+panic checker. Update #8606 Change-Id: I6a159bbc8da5b2b7ee835c0cd1fc565575b58c46 Reviewed-on: https://go-review.googlesource.com/c/go/+/237919 Run-TryBot: Keith Randall <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
Change https://golang.org/cl/237921 mentions this issue: |
We're using sort.SliceStable, so no need to keep track of indexes as well. Use a more robust test for whether a node is a call. Add a test that we're actually reordering comparisons. This test fails without the alg.go changes in this CL because eqstring uses OCALLFUNC instead of OCALL for its data comparisons. Update #8606 Change-Id: Ieeec33434c72e3aa328deb11cc415cfda05632e2 Reviewed-on: https://go-review.googlesource.com/c/go/+/237921 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
Just a note that I think that we made a decision here: we compare structs for equality by comparing field by field, and exiting early when two fields are unequal. But I don't think that decision was ever added to the spec. (@griesemer) |
To nag again, this issue affects array comparison order too, and it remains unconfirmed whether arrays were intentionally dropped from the accepted retitling on June 10, 2020. |
It seems to me that the same problems that might occur with unspecified struct field comparison order would apply to array comparisons. I'll send out a CL specifying both, in the spirit of this issue. We can discuss on the issue if we want to keep the clarification for arrays. |
Change https://go.dev/cl/449536 mentions this issue: |
I feel like my comments aren't being heard. My original issue report from 2014 mentions structs and arrays equally: they were both mentioned in the issue title and the very first sentence of the issue body. Whenever I replied mentioning structs, I wrote "struct/array" (1, 2, 3). @rsc retitled it in June 2020 to remove the mention of arrays. I explicitly asked that same day if that was intentional, and never got a response. I asked again 6 days ago after @ianlancetaylor pinged the issues, and still I'm not getting any acknowledgement. |
I agree with @griesemer that this should apply to arrays as well as structs. |
The text was updated successfully, but these errors were encountered: