关于无符号整数溢出的规范说:
对于无符号整数值,操作+, - ,*和<<以2n为模计算,其中n是无符号整数类型的位宽.松散地说,这些无符号整数运算在溢出时丢弃高位,程序可能依赖于''环绕''.
我尝试测试它,但结果不一致 - http://play.golang.org/p/sJxtSHbigT:
package main
import "fmt"
func main() {
fmt.Println("test")
var num uint32 = 1 << 35
}
Run Code Online (Sandbox Code Playgroud)
这给出了错误:
prog.go:7: constant 34359738368 overflows uint32
[process exited with non-zero status]
Run Code Online (Sandbox Code Playgroud)
但根据规范应该没有错误,而是我应该看到0.
小智 6
您引用的规范特指"操作+, - ,*和<<"的结果.您正在尝试定义常量,而不是查看其中一个操作的结果.
您也不能将这些超大值用于这些操作的输入.编译器不会为您包装任何值; 这只是那些操作的运行时行为.
package main
import "fmt"
func main() {
var num uint32 = 1 + 1 << 35
fmt.Printf("num = %v\n", num)
}
Run Code Online (Sandbox Code Playgroud)
prog.go:6: constant 34359738369 overflows uint32
[process exited with non-zero status]
Run Code Online (Sandbox Code Playgroud)
这是一个有趣的例子.
var num uint32 = (1 << 31) + (1 << 31)
fmt.Printf("num = %v\n", num)
Run Code Online (Sandbox Code Playgroud)
prog.go:6: constant 4294967296 overflows uint32
[process exited with non-zero status]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,编译器会尝试(1 << 31) + (1 << 31)在编译时进行求值4294967296,生成常量值,该值太大而不适合.
var num uint32 = (1 << 31)
num += (1 << 31)
fmt.Printf("num = %v\n", num)
Run Code Online (Sandbox Code Playgroud)
num = 0
Run Code Online (Sandbox Code Playgroud)
在这种情况下,添加是在运行时执行的,并且值会像您期望的那样回绕.