-
Notifications
You must be signed in to change notification settings - Fork 18k
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/compile: duplicate swtich case constant bool expressions are accepted by compiler #28357
Comments
Ah, looks this is mentioned in spec:
But why boolean case expresssions are exceptions? And does "the current compilers" includes gccgo, if true, can we think this is a bug of gccgo (for thinking the string switch is valid.) |
The following code also compiles failed by gc, but passed by gccgo. package main
func main() {
var a interface{}
switch a {
case nil:
case nil: // duplicate case nil (value <nil>) in switch
}
} Is gc too restricted (than spec) here? |
And this package main
func main() {
var a int64
switch a {
case int64(123):
case int32(123):
}
} gc reports:
I think the second error message is not necessary. (gccgo does it right here) |
I'd imagine this is to allow switch statements of the form:
Two Either way, @griesemer will know. |
go/src/cmd/compile/internal/gc/swt.go Line 637 in 5a7cfbc
|
This is intentional, and we aren’t going to change it for the reasons given in the comment referenced above. |
then would it be better to also relax for other kinds of types? |
And can't case GOARCH == "arm" && GOARM == "5":
case GOARCH == "arm": be written as case GOARCH == "arm":
if GOARM == "5" {
. ..
} else {
...
} ? Though I admit that the former is a little more graceful. |
Technically, More generally, "implementation restrictions" are really "language restrictions": If the primary compilers follow the implementation restrictions, it doesn't really matter if a Go program is valid per the spec; "correct" compilers may refuse them anyway. For all practical purposes, those programs are "incorrect". And it also does mean that all compilers really should follow the same implementation restriction fairly closely (unless they are considered "buggy"). We call these restrictions "implementation restrictions" because we're a bit too nervous to make them part of the language proper: Some of these rules are rather pragmatic (e.g., we ignore duplicate bools above), may change over time, and generally have a slightly "unsavory" smell to them compared to the rest of the spec. Also, some of the restrictions would put undue burden on the specifics of a particular implementation. For instance, the implementation of the compiler's constant arithmetic differs considerably between cmd/compile, gccgo, and go/types. The latter uses 100% exact arithmetic (rational numbers) unless the fractions become too huge, while the former two always use just floats with very large mantissas and exponents. It's easily possible to create programs that are 100% correct and accepted by go/types but refused by the compilers. And vice versa. It's not clear that we want to pin down the implementation enough such that such corner cases are not possible. It might be better to avoid such code. Software engineering is a real world thing and compromised by that real world. |
@griesemer thanks for the wonderful explanation. I agree totally. |
What version of Go are you using (
go version
)?go version go1.11.1 linux/amd64
Does this issue reproduce with the latest release?
yes
What did you do?
What did you expect to see?
The first switch block should also compile error.
What did you see instead?
Compiler think the first switch block is valid.
BTW, gccgo also think the string switch is valid.
The text was updated successfully, but these errors were encountered: