C 標準では、負でないシフト数に対する右シフト演算の動作が明確に定義されています。ただし、シフト数がシフトされる型の幅を超える場合、動作は未定義とみなされます。
次のコードを考えてみましょう。
<code class="cpp">unsigned int val = 0x0FFFFFFF; unsigned int res = val >> 34; // res should be 0 by C++ standard</code>
C 標準によれば、34 は負の数ではない場合、結果の値 res は 0 になるはずです。ただし、GCC はこのコード スニペットに対して警告を発し、ゼロ以外の結果を生成します。
この場合の GCC の動作は、次の抜粋で説明できます。ドラフト C 標準セクション 5.8 シフト演算子:
結果の型は、昇格された左オペランドの型です。 右オペランドが負の場合、またはプロモートされた左オペランドのビット長以上の場合、動作は未定義です。
この場合、 unsigned int が 32 ビット以下の場合、シフト数 34 は昇格された左オペランドの幅を超えます。したがって、この動作は未定義であり、GCC の警告は正当です。
このコンテキストにおける未定義の動作は、未定義の値を指すものではないことに注意することが重要です。代わりに、動作が実装定義であり、コンパイラやプラットフォームによって異なる可能性があることを意味します。この場合、Intel プラットフォームでの GCC の動作は C 標準の期待と一致しません。
以上がGCC が過剰なシフト数の右シフト演算で未定義の動作を引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。