Skip to content
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: multiple equal integer constant switch case values should be illegal #4524

Closed
griesemer opened this issue Dec 11, 2012 · 14 comments
Closed
Labels
Documentation Issues describing a change to documentation. FrozenDueToAge
Milestone

Comments

@griesemer
Copy link
Contributor

The spec does not prohibit multiple integer constant case values from being equal:

var x int
switch x {
case 1:
case 1:
}

is not illegal according to http://tip.golang.org/ref/spec#Switch_statements . However,
running this program ( http://play.golang.org/p/MkI5XjE1TS ) results in:

prog.go:7: duplicate case in switch
    previous case at prog.go:6

using the gc compiler.
@griesemer
Copy link
Contributor Author

Comment 1:

The gc compiler also rejects duplicate float and string case values, but not complex
values or booleans.
In general, duplicate constants should probably be rejected.

@rsc
Copy link
Contributor

rsc commented Dec 11, 2012

Comment 2:

I certainly want to reject duplicate bools and complex too, but I think we missed the
boat.
For now let's reject duplicate int, float, and string in the spec and leave bool and
complex for Go 2.

Labels changed: added priority-later, removed priority-triage.

@rsc
Copy link
Contributor

rsc commented Feb 9, 2013

Comment 3:

Owner changed to ---.

Status changed to Started.

@rsc
Copy link
Contributor

rsc commented Feb 12, 2013

Comment 4:

Aborted attempt at http://golang.org/cl/7311067. Leaving for gri.

Status changed to Accepted.

@rsc
Copy link
Contributor

rsc commented Feb 12, 2013

Comment 5:

In addition to the shortcoming in the initial report, the switch discussion also does
not say that == must be defined on the switch expression, nor does it say that the case
expressions must be comparable to the switch expression.

@rsc
Copy link
Contributor

rsc commented Mar 21, 2013

Comment 6:

Labels changed: removed go1.1.

@griesemer
Copy link
Contributor Author

Comment 7:

There are two orthogonal issues here:
1) definition of the switch semantics
2) restrictions on top of 1
Regarding 1: The idea of the expression switch statement was (from day one) that it
should behave exactly like the corresponding if-else-if sequence (with the extra of
fallthrough, but that is not an inherent complication). By defining a switch in terms of
an if-else-if sequence we get an immediate and accurate definition of its behavior, it
explains why an if-else-if sequence can always be rewritten into a respective switch
statement and vice versa, and it also informs an straight-forward compiler how to
implement it  (e.g., by rewriting the AST to an if-else-if sequence). It also explains
corner-case situations such as:
    switch 1<<100 {
    case 1<<100:
    }
    var x int
    switch 1.0 {
    case x:
    }
etc., which are currently not accepted by 6g or gccgo for no good reasons. Going away
from the switch if-else-if equivalence will make the spec and programming in Go more
complicated.
2) It is possible to add orthogonal restrictions on top of the semantics proposed in 1).
The typical restriction is to disallow multiple equal constant case values as in:
    var x int
    switch x {
    case 1:
    case 1:
    }
At the moment, gc looks at duplicate integer, floating point, and string values (but
ignores duplicate complex or boolean values); gccgo ignores duplicate boolean, string,
and complex values. The situation is more complex when the tag expression is of
interface type:
    var x interface{}
    switch x {
    case 1:
    case 1.0:
    case 1e0:
    }
In this case 1 will be typed as int, while 1.0 and 1e0 will be typed as float64 and thus
1.0 and 1e0 would be the same constant, but not so 1.
There are also good reasons for not having a restriction at all: For instance, any
switch statement with more than 2 constant boolean case values will have duplicates, but
those constants may be defined globally and enable/disable functionality that might be
platform-specific. In such a scenario, we would not want a compiler error depending on
configuration. The same applies to string constants, and to some extent integer
constants.
It may be reasonable to say that the restriction should apply to numeric values only,
and perhaps even to integers only because that's a common scenario (ioata-defined
integers of an "enum" type).
After discussing this w/ r, I am leaning towards not having any restrictions enforced by
the compiler at all. r suggested that go vet might be better suited for this job.

@rsc
Copy link
Contributor

rsc commented Oct 29, 2013

Comment 8:

I think it is a mistake to remove the restrictions we have today.

@griesemer
Copy link
Contributor Author

Comment 9:

The main problem with the restrictions we have today is that they are not documented,
nor consistently implemented.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 10:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 11:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 12:

Labels changed: added repo-main.

@griesemer
Copy link
Contributor Author

Comment 13:

Owner changed to @griesemer.

@griesemer griesemer added accepted Documentation Issues describing a change to documentation. labels Sep 10, 2014
@griesemer griesemer self-assigned this Sep 10, 2014
@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@gopherbot
Copy link
Contributor

CL https://golang.org/cl/12711 mentions this issue.

@mikioh mikioh modified the milestones: Go1.5, Unplanned Jul 31, 2015
@golang golang locked and limited conversation to collaborators Aug 5, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation Issues describing a change to documentation. FrozenDueToAge
Projects
None yet
Development

No branches or pull requests

4 participants