ビット単位シフトにおける未定義の動作と実装定義の動作
ビット単位の左シフト演算子 (<<) は、その動作に関する疑問を引き起こします負の左側オペランドを使用します。この記事では、この操作によって C では未定義の動作が発生するのに、C では実装定義の動作のみが発生する理由を検討します。
C の未定義の動作
ISO C99 によると、負のオペランドを指定すると、未定義の動作が発生します。これは、標準では、結果が左のオペランドと 2E2 の積であり、結果の型の範囲を法とすることが規定されているためです。ただし、左のオペランドが負の場合、このような計算では、符号付き型のコンテキストで未定義の結果が生じる可能性があります。
C の明確な動作
とは対照的に、 C、C は、符号なしオペランドを左シフトすると期待される数学的乗算が得られることを指定します。ただし、符号付き型の場合、結果が結果型の表現可能な範囲を超えた場合の未定義の動作も C で定義されています。したがって、 C では、左シフトの負のオペランドは未定義のままです。
発散の理由
C の異なるアプローチの理由は、おそらく、オーバーフローの可能性があるため、否定的な動作はすでに未定義です。すべての負のケースをカバーするように定義を拡張することで、標準が簡素化され、未定義の動作が明確になりました。
実装で定義された右シフト動作
負のオペランドの右シフトは実装です。符号拡張とゼロ埋め込みのどちらかを選択する必要があるため、C と C の両方で定義されています。符号拡張では、空いたビットに元の符号ビットが保持されますが、ゼロ充填ではそれらがゼロに置き換えられます。異なるコンパイラやプラットフォームではいずれかの動作が選択される可能性があるため、実装定義の性質となります。
要約
C では、負のオペランドを無条件に左シフトすると、未定義の動作が発生します。 。 C では、このような演算は符号付き型に対しても定義されていません。一方、負のオペランドの右シフトは、符号拡張とゼロ埋めの選択により、両方の言語で実装定義されています。
以上がC と C のビット単位のシフトにおける未定義の動作と実装定義の動作の違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。