I propose that the Go language and implementations be changed to reject a constant assignment to a variable of type int (or uint) if the constant would overflow a 32-bit int (or uint), regardless of the size of int on the current GOOS.
That is, on amd64, this would be rejected:
const MaxInt64 = 1<<63 - 1
var x int = MaxInt64
Currently that passes on 64-bit platforms but fails when people cross-compile it to Raspberry Pis or run it on the playground (https://play.golang.org/p/4PK8z_WBKi).
This bites people like in https://github.com/GoogleCloudPlatform/google-cloud-go/issues/648 where it lurks unnoticed by users & continous builds for a long time, until somebody builds the code for the increasingly rare 32-bit machines.
/cc @griesemer
Have you thought about making this a go vet error instead? Or is "breaking" these programs on 64-bit acceptable, given that they're not valid programs on all architectures?
I don't think the lack of proper release testing of some projects for more platforms/architectures justifies bending the language to "solve" the problem. (And I was bitten this way by my own code more than once.)
@mvdan, a vet error would be a good first step (especially if #18084 happens), but I still consider these invalid programs in all cases.
@cznic, I would normally agree with you on that (that the answer is testing), but in this case I think the language just shouldn't permit it in the first place. I don't think it should be possible to write a portable Go program (no syscall, unsafe, etc) program that runs on some machines but not others.
Based on discussion with @bradfitz, this is only about assigning an untyped constant to an int/uint/uintptr. The following are OK because the constants are typed:
const X int = 1<<63-1
var x int = X
var y uintptr = ^uintptr(0)
I'm not in favour of this proposal, the situations it addresses are pretty
rare.
However if you're serious about this, what about this counter proposal:
Drop support for typed integer constants if the type is machine size
dependant.
That is, rather the clamping into/uint to 31/32 bits ... If someone does
want to make their numeric constant typed, they have to be precise about
how many bits they need.
Thoughts?
Dave
On Fri, 9 Jun 2017, 03:15 Brad Fitzpatrick notifications@github.com wrote:
I propose that the Go language and implementations be changed to reject a
constant assignment to a variable of type int (or uint) if the constant
would overflow a 32-bit int (or uint), regardless of the size of int on
the current GOOS.That is, on amd64, this would be rejected:
const MaxInt64 = 1<<63 - 1
var x int = MaxInt64Currently that passes on 64-bit platforms but fails when people
cross-compile it to Raspberry Pis or run it on the playground (
https://play.golang.org/p/4PK8z_WBKi).This bites people like in GoogleCloudPlatform/google-cloud-go#648
https://github.com/GoogleCloudPlatform/google-cloud-go/issues/648 where
it lurks unnoticed by users & continous builds for a long time, until
somebody builds the code for the increasingly rare 32-bit machines./cc @griesemer https://github.com/griesemer
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/golang/go/issues/20616, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAcAwPxGS2A0jIynov0DfsqL3BsXfaFks5sCCwZgaJpZM4N0Xpc
.
@davecheney, so then I can't write ^uintptr(0) at all?
I didn't say it was a _good_ counter proposal :) But I posit that it's a
little more consistent than making const x int limited to a number that is
smaller than var x int.
On Tue, Jun 13, 2017 at 11:53 PM, Russ Cox notifications@github.com wrote:
@davecheney https://github.com/davecheney, so then I can't write
^uintptr(0) at all?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/golang/go/issues/20616#issuecomment-308123054, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAcA1fQH9mTCDpUaWgvPsuzCAHhGxf8ks5sDpRogaJpZM4N0Xpc
.
It's currently confusing in Go that the expression uint(-1) does not compile. This proposal would seem to extend that to saying that the expression int64(0x100000000) would not compile. Russ's comment above suggests that we only want to give an error on an attempt to assign an untyped constant to a variable of type int, but that isn't something we have in the language right now, so that would need to be more clearly specified.
As long as int is part of the language, it will be a potential failure point for cross-platform development. This proposal would solve compile-time failures, but leave the much harder to spot (and to test for) run-time bugs (i.e. when an int variable suddenly overflows). Note that 32 bit platforms are still the norm for embedded development, and TinyGo has shown that Go has a good potential there.
IMHO the right solution would be to remove int altogether, and use int32 as the default integer type. This is the approach taken by Rust. (see RFC 212)
I don't think there is any good reason to choose int64 as the default, even on 64 bit platforms: 32 bit integers already provide a reasonable range of numbers, are most of the time faster, and safe to convert to the default float type.
Another solution would be proposal #19623
Yes, I think this proposal only plasters over the problem, so I am not in favor of it. #19623 would probably be the better solution.
Most helpful comment
Have you thought about making this a go vet error instead? Or is "breaking" these programs on 64-bit acceptable, given that they're not valid programs on all architectures?