Goではintのサイズはアーキテクチャによって異なり、32ビットか64ビットのどちらかということになっている。32ビットのx86では32ビットだし、x86-64では64ビットだ。ときどきビット演算などでintのサイズがどちらなのかを知りたいことがある。そういうときにはどうすればいいだろうか?
結論から先に言うと次の式を使うとintSizeはアーキテクチャに応じて32か64のどちらかになる。
const intSize = 32 << (^uint(0) >> 63)
uintとintは最上位ビットが符号ビットとみなされるかどうかという違いがあるだけで、同じサイズであることが保証されている。uint(0)は型なしの定数0をuintに型変換しているので、その値は32ビットか64ビットのどちらかの符号なし整数0になる。^は単項演算子のXORなので、ビットが反転されて、^uint(0)は32ビットか64ビットのすべてのビットが1の値ということになる。これを63ビット右にシフトすると、32ビットの場合は全部シフトアウトされてしまって0だけが残る。64ビットの場合は最上位ビットだけが最下位ビットとして残って結果は1になる。
32 << 0は32だし、32 << 1は64だ。従ってintSizeは32か64になる。
というわけで上記の式では正しいアーキテクチャ依存の値が得られるのである。得られた値はコンパイル時に決まる定数(const)なので、これを使うパフォーマンス上のペナルティは定数32や64を直接書くのと変わらない。