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

cmd/compile: untyped int constant gives me an overflow error #66776

Closed
leabit opened this issue Apr 11, 2024 · 3 comments
Closed

cmd/compile: untyped int constant gives me an overflow error #66776

leabit opened this issue Apr 11, 2024 · 3 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.

Comments

@leabit
Copy link

leabit commented Apr 11, 2024

Go version

go version go1.22.0 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/leabit/.cache/go-build'
GOENV='/home/leabit/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/leabit/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/leabit/go'
GOPRIVATE=''
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='0'
GOMOD='/dev/null'
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 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1175911802=/tmp/go-build -gno-record-gcc-switches'

What did you do?

As far as I know and understand, untyped numeric constants live, as Rob Pike says, in some kind of "ideal" world without any kind of limits (they are just like regular numbers from the real world).

So, I write the following two programs:

(1)

package main

func main() {
	const c1 = 10_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
}

(2) - c1 just got one more zero (that is, multiplied by 10)

package main

func main() {
	const c1 = 100_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
}

What did you see happen?

Running the first program went as I expected, it compiles. So, even though the given number is much larger than the default type (int), it is still untyped int constant that lives in "ideal" (real) word, thus the overflow of default type doesn't have any effect. All expected.

However, the second program does not compile. It gives me constant overflow (InvalidConstVal) error.

What did you expect to see?

I expect both programs to compile. Unfortunately, the second one doesn't compile due to overflow which, while unrelated to the default type, I don't expect to see in any form in the case of untyped numbers and this "ideal" world.

Additionally, if I add . at the end of the constant (c1) and, by that, make it untyped float constants instead of untyped int constant, everything starts to work as I expected. In other words, no limits nor overflow appear (actually it does, but it is because the constant is too long; got the error message excessively long constant - 10.000+ chars).

Is this the expected behavior or a bug? Why does the untyped int constants have a limit, while an untyped float constants don't? Shouldn't untyped int constants also be unlimited and "overflow-free", that is, limited in the same way as untyped float constants (only by the number of characters)?

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Apr 11, 2024
@seankhliao
Copy link
Member

As the post mentions, untyped constants still have a default type through which it carries its value, the untyped part only means explicit type conversions aren't needed.

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Apr 11, 2024
@leabit
Copy link
Author

leabit commented Apr 11, 2024

@seankhliao

As the post mentions, untyped constants still have a default type through which it carries its value, the untyped part only means explicit type conversions aren't needed.

As I wrote, overflow doesn't happen because of the default type, but it still happens, and it only happens in the case of untyped int constants, not untyped float constants.

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

It's not a "general discussion or questioning" even though it may seem that way at first glance (my mistake). As I wrote at the end, I expect the same behavior for untyped int constants and untyped float constants, so I suggest (propose) making the same limits ("overflow-free") for them. However, I'm not sure if the difference was made on purpose or if it's just a bug that nobody noticed until now.

It is not clear to me why the issue was closed.

@ianlancetaylor
Copy link
Contributor

See the implementation restriction in the spec at https://go.dev/ref/spec#Constants :

Implementation restriction: Although numeric constants have arbitrary precision in the language, a compiler may implement them using an internal representation with limited precision. That said, every implementation must:

Represent integer constants with at least 256 bits.
Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed binary exponent of at least 16 bits.
Give an error if unable to represent an integer constant precisely.
Give an error if unable to represent a floating-point or complex constant due to overflow.
Round to the nearest representable constant if unable to represent a floating-point or complex constant due to limits on precision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.
Projects
None yet
Development

No branches or pull requests

4 participants