Open bradfitz opened 7 years ago
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 = 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 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.
I propose that the Go language and implementations be changed to reject a constant assignment to a variable of type
int
(oruint
) if the constant would overflow a 32-bitint
(oruint
), regardless of the size ofint
on the current GOOS.That is, on
amd64
, this would be rejected: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