型幅を超えるカウントによる右シフト: 未定義の動作
C では、右シフト演算子 (>>) は論理和を実行します。整数の算術シフト演算。この演算子の動作は一般に明確に定義されていますが、未定義の動作を引き起こす可能性のある特定の条件があります。
そのような条件の 1 つは、シフト数がシフトされる型の幅を超える場合です。 C 標準では、「右側のオペランドが負の場合、またはプロモートされた左側のオペランドのビット長以上の場合、動作は未定義です」と明示的に述べられています。
これは、整数をカウントだけシフトすることを意味します。オペランドが符号付きであるか符号なしであるかに関係なく、そのビット幅以上は未定義です。理論的には、これは、そのようなシフトの結果は保証されず、実装ごとに異なる可能性があることを意味します。
しかし、実際には、一部のコンパイラはそのような場合に特定の動作を実装する可能性があります。たとえば、GCC はシフト数が型の幅を超えると警告を発行しますが、エラーは発生しません。この動作は C 標準では明示的に定義されておらず、プラットフォームによって異なる場合があります。
提供されたコード スニペットでは、符号なし整数の 34 による右シフトが実行されます。
<code class="cpp">unsigned int val = 0x0FFFFFFF; unsigned int res = val >> 34;</code>
シフト カウントが unsigned int 型の幅 (通常は 32 ビット) より大きいため、C 標準に従って計算された結果は 0 になるはずです。ただし、GCC は警告を発し、代わりに結果を 67108863 として計算します。
この不一致は、GCC がこの未定義のケースに対して特定の動作を実装しているために発生します。生成されたアセンブリ コードは、論理右シフトを実行し、結果の符号拡張を行わない SHRL 命令を使用します。その結果、結果はゼロではなく、むしろゼロ以外の値になります。
したがって、 C でシフト演算を扱うときは、シフト数が型の幅を超えないようにすることが重要です。シフトされている。型の幅を超えると、さまざまなコンパイラやプラットフォーム間で未定義の動作や信頼性の低い結果が発生する可能性があります。
以上がC で型の幅を超える数を右にシフトするとどうなりますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。