在命令行和游乐场进行整数溢出设置

This program runs fine one my machine (go1.2.1 linux/amd64):

package main

import "fmt"

const bigint = 1<<62

func main() {
    fmt.Println(bigint)
}

But with the go playground, it gives overflow error - http://play.golang.org/p/lAUwLwOIVR

It seem that my build is configured with 64 bits for integer constans, playground configured with 32 bits.

But spec say that implementation must give at least 256 bits of precision for constants?

Also see code in my other question -- the scanner standard package has code:

const GoWhitespace = 1<<'\t' | 1<<'
' | 1<<'' | 1<<' '

Since space is 32, this don't work on 32-bit playground at all.

How can this be?

Constants in general

Constants itself are not limited in precision but when used in code they are converted to a suitable type. From the spec:

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 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. For instance, 3.0 can be given any integer or any floating-point type, while 2147483648.0 (equal to 1<<31) can be given the types float32, float64, or uint32 but not int32 or string.

So if you have

const a = 1 << 33
fmt.Println(a)

you will get an overflow error as the default type for integer constants int can't hold the value 1 << 33 on 32 bit environments. If you convert the constant to int64 everything's fine on all platforms:

const a = 1 << 33
fmt.Println(int64(a))

Scanner

The constant GoWhitespace is not directly used in the scanner. The Whitespace attribute used in the Scanner type is of type uint64 and GoWhitespace is assigned to it:

s.Whitespace = GoWhitespace

This means you deal with a uint64 value and 1 << ' ' (aka. 1 << 32) is perfectly valid.

Example (on play):

const w = 1<<'\t' | 1<<'
' | 1<<'' | 1<<' '

c := ' '

// fmt.Println(w & (1 << uint(c))) // fails with overflow error
fmt.Println(uint64(w) & (1 << uint(c))) // works as expected

As stated by nemo, you can give a type to your constant. Just specify int64 and it works fine :)

http://play.golang.org/p/yw2vsvMigk

package main

import "fmt"

const bigint int64 = 1<<62

func main() {
    fmt.Println(bigint)
}