2016-04-04 3 views
1

The Go Programming Language book、運動6.5、著者はこの式を使用して私たちに語った:なぜ獣医報告書のuint(0)が63のシフトには小さすぎるのでしょうか?

32 << (^uint(0) >> 63) 

プラットフォームは32ビットまたは64ビットであるかどうかをチェックします。

式は非常に明確であり、我々は単純なコードで結果を確認することができます。

package main 

import "fmt" 

func main() { 
    fmt.Println(32 << (^uint(0) >> 63)) 
} 

コード32ビットプラットフォーム上のプリント064 64ビットプラットフォーム上。

$ go vet ex6-5.go 
ex6-5.go:6: ^uint(0) might be too small for shift of 63 
exit status 1 

はなぜgo vetが警告することを私に示してい:

ただし、ファイルをgo vetを使用して、私は警告を受けますか?どうすればそれを防ぐことができますか?

答えて

2

これは、これはまた、使用できた理由である63

だけ右シフトをあなたのために十分uintは固定ビット単位の長型ではないので、それは32ビットと短い可能性があり、そうではありませんプラットフォームをテストするこの式は、uintがプラットフォーム上で最も効率的なintタイプを使用するためです。

は、32ビットプラットフォーム上の場合、uintは、32ビット長であるので、右シフトは32 << 0の結果として最終的に32を引き起こす0を与えるだろう。しかし、64ビットプラットフォームでは、uintは64ビットを与えます。したがって、右シフト63ビットは0の代わりに1の代わりになり、32 << 164となるので、最後に64という結果になります。

獣医のソースコードを見てみましょう:

71  case types.Int, types.Uint, types.Uintptr: 
72   // These types may be as small as 32 bits, but no smaller. 
73   size = 32 
74   msg = "might be " 
... 
78  if amt >= size { 
79   ident := f.gofmt(x) 
80   f.Badf(node.Pos(), "%s %stoo small for shift of %d", ident, msg, amt) 
81  } 

限り、あなたはgo vetshiftをチェックして、UINTおよび63ビットの右シフトを使用しているとして、脱出する方法はありません、と言うことですその小切手あなたはフラグを提供することで、チェックすることをスキップすることを試みることができる:

go tool vet -shift=false yourfile.go 
1

なぜ獣医が警告ことを私に示して行くのですか?どうすればそれを防ぐことができますか?

nevetsの答えは、提案された:

go tool vet -shift=false yourfile.go 

を:しかし

あなたはフラグを提供することで、チェックすることをスキップすることを試みることができるあなたはgo tool vetを使用しないでください。 go vetのみ。またはこの場合は、フラグを渡す必要があるためです。

しかし、go go 1。this threadを参照してください:変更されます(Q1 2018)10、

あなたは一般的に「go tool compile」を実行しないと同じように、本質的にvet(に働いている人にのみ有用である、「go tool vet」を使用しないでください。 )。

は以前あなたが獣医フラグを制御したい場合は、「go tool vet」を使用するために必要な、しかしは「go vetは」今「go tool vet」はを行い、すべてのフラグを受け付けます。 (「go help vet」を参照)

したがってgo vet -shift=false yourfile.goで十分です。

関連する問題