Closed3

Goのfmt/scan.goを読んでみる

nabeyangnabeyang

読んでるのは1.17.6です。基本的には独り言で、特に役立つ情報はないと思います。

nabeyangnabeyang

scanInt

657行目からのところで、オーバーフローチェックしているけども、これは32bitの時しか働かないよね。

	i, err := strconv.ParseInt(tok, base, 64)
	if err != nil {
		s.error(err)
	}
	n := uint(bitSize)
	x := (i << (64 - n)) >> (64 - n)
	if x != i {
		s.errorString("integer overflow on token " + tok)
	}

実験

main.go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	rr := bufio.NewReader(os.Stdin)
	var n int
	_, err := fmt.Fscan(rr, &n)
	fmt.Println(err)
	fmt.Println(n)
}
input.txt
2147483648

この状態で次のように実行するとオーバーフローチェックに引っかかる。

$ GOARCH=386 go run . < input.txt 
integer overflow on token 2147483648
0

なんだけど、64bitもオーバーフローさせるように、input.txtを変える。

input.txt
9223372036854775808

すると、次のようにstrconv.ParseIntでエラーになって、なんか一貫性が無い。

$ GOARCH=386 go run . < input.txt 
strconv.ParseInt: parsing "9223372036854775808": value out of range
0
$ GOARCH=amd64 go run . < input.txt 
strconv.ParseInt: parsing "9223372036854775808": value out of range
0
nabeyangnabeyang

consumeの490行目からr != eofって要らないような。上でr == eofだとそこまで行かない。

	if r != eof && accept {
		s.UnreadRune()
	}
このスクラップは2022/02/22にクローズされました