Description
Go version
go version go1.22.0 linux/amd64
Output of go env
in your module/workspace:
~/play/mapsample$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/branden/.cache/go-build'
GOENV='/home/branden/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/branden/go/pkg/mod'
GONOPROXY='*.redacted.net'
GONOSUMDB='*.redacted.net'
GOOS='linux'
GOPATH='/home/branden/go'
GOPRIVATE='*.redacted.net'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/branden/play/mapsample/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2983741865=/tmp/go-build -gno-record-gcc-switches'
What did you do?
Used a constant representable as int in a range
clause.
https://go.dev/play/p/Zkd_wK5-Y20
for range 1e0 {
fmt.Println("Hello, 世界")
}
(More realistically, I wrote a number of iterations for a test as const N = 2e5
, then used N
in a range clause.)
What did you see happen?
./prog.go:8:12: cannot range over 1e0 (untyped float constant 1)
What did you expect to see?
Since constant 1e0
is representable as int, I expect it to be implicitly typed as such in a range
clause. AFAIK this is the only place the compiler rejects floating-point constants representable as an integer type where an integer expression is expected; e.g., [1e0]struct{}{}
is accepted.
Per the spec's section on for
loops with range
clauses:
The expression on the right in the "range" clause is called the range expression, its core type must be an array, pointer to an array, slice, string, map, channel permitting receive operations, or an integer.
...
If the range expression is a (possibly untyped) integer expressionn
,n
too must be assignable to the iteration variable; if there is no iteration variable,n
must be assignable to int.
along with the section on constants:
A constant may be given a type explicitly by a constant declaration or conversion, or implicitly when used in a variable declaration or an assignment statement or as an operand in an expression. It is an error if the constant value cannot be represented as a value of the respective type.
Arguably, the fact that range clauses specify "a (possibly untyped) integer expression" is the justification that floating point constants are always rejected. In particular, that section is the only place where the phrase "integer expression" appears in the spec. However, the section on constants also classifies rune constants separately from integer constants ("Rune, integer, floating-point, and complex constants are collectively called numeric constants"), yet the compiler does not reject a rune constant in a range clause: https://go.dev/play/p/eh307dPM6s5. So, my reading of the spec is that both rune and floating-point constants should be either accepted or rejected.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status