1
func main() {
   var a = math.MaxInt64
   fmt.Println(a + 1)             //-9223372036854775808
   fmt.Println(math.MaxInt64 + 1) //constant 9223372036854775808 overflows int
}

why the two ways perform differently?
Himanshu
  • 12,071
  • 7
  • 46
  • 61
Ryan
  • 21
  • 2
  • have your run your program it is giving error for both as overflow – Himanshu May 03 '18 at 02:52
  • The one is a constant the other a variable. One is evaluated at compile time, the other at runtime. Read about constants in Go in the Blog. – Volker May 03 '18 at 03:36

2 Answers2

4

In the second example math.MaxInt64 + 1 is a constant expression and is computed at compile time. The spec says:

Constant expressions are always evaluated exactly; intermediate values and the constants themselves may require precision significantly larger than supported by any predeclared type in the language.

However when the value of the expression is passed to fmt.Println it has to be converted into a real predeclared type, in this case an int, which is represented as a signed 64 bit integer, which is incapable of representing the constant.

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.

In the first example a + 1 is not a constant expression, rather it's normal arithmetic because a was declared to be a variable and so the constant expression math.MaxInt64 is converted to an int. It's the same as:

var a int = math.MaxInt64

Normal arithmetic is allowed to overflow:

For signed integers, the operations +, -, *, /, and << may legally overflow and the resulting value exists and is deterministically defined by the signed integer representation, the operation, and its operands. No exception is raised as a result of overflow.

With minor modifications you can make the examples the same:

func main() {
    const a = math.MaxInt64
    fmt.Println(a + 1)             //constant 9223372036854775808 overflows int
    fmt.Println(math.MaxInt64 + 1) //constant 9223372036854775808 overflows int
}
Caleb
  • 9,272
  • 38
  • 30
1

It is showing an error because if you check the type of a constant value of 1 it will show you that you are actually adding int to a int64 value. So first declare a variable of type int64 and than add to const math.MaxInt64 just like that

package main

import (
    "fmt"
    "math"
)

func main() {
   var a int64 = 1 
   fmt.Println(math.MaxInt64 + a)             //-9223372036854775808
   fmt.Printf("%#T", 1)
   //fmt.Println(math.MaxInt64 + 1) //constant 9223372036854775808 overflows 
}
Himanshu
  • 12,071
  • 7
  • 46
  • 61