29

私のコンパイラでは、次の擬似コード(値がバイナリに置き換えられています):

sint32 word = (10000000 00000000 00000000 00000000);
word >>= 16;

word次のようなビットフィールドを持つを生成します。

(11111111 11111111 10000000 00000000)

私の質問は、すべてのプラットフォームとC ++コンパイラでこの動作に依存できますか?

4

5 に答える 5

30

次のリンクから:
INT34-C。負のビット数、またはオペランドに存在するビット数以上で式をシフトしないでください。

非準拠のコード例(右シフト)
の結果は、ビット位置E1 >> E2E1右シフトされます。E2符号なしの型がある場合E1、または符号付きE1の型と非負の値がある場合、結果の値はE1 /2E2の商の整数部分になります。が符号付きタイプで負の値の場合E1、結果の値は実装で定義され、算術(
算術(符号付き)シフト
符号付き)シフトまたは論理(符号なし)シフトのいずれかになります。
論理(符号なし)シフト
この非準拠のコード例では、右のオペランドがまたはより大きいかどうかをテストできません。プロモートされた左オペランドの幅に等しく、未定義の動作を許可します。

unsigned int ui1;
unsigned int ui2;
unsigned int uresult;

/* Initialize ui1 and ui2 */

uresult = ui1 >> ui2;

右シフトが算術(符号付き)シフトとして実装されているのか、論理的(符号なし)シフトとして実装されているのかを推測することも、脆弱性につながる可能性があります。推奨事項INT13-Cを参照してください。符号なしオペランドでのみビット演算子を使用してください

于 2011-09-22T23:05:03.240 に答える
19

最新のC++20ドラフトから:

符号付き整数型の右シフトは、符号拡張を実行する算術右シフトです。

于 2019-02-01T15:52:48.857 に答える
14

いいえ、この動作に依存することはできません。負の量の右シフト(あなたの例が扱っていると思います)は実装で定義されています。

于 2011-09-22T22:51:56.690 に答える
7

C ++では、違います。実装やプラットフォームに依存します。

他のいくつかの言語では、そうです。たとえば、Javaでは、>>演算子は、常に左端のビットを使用して入力するように正確に定義されています(これにより、符号が保持されます)。>>>演算子は0を使用して入力します。したがって、信頼できる動作が必要な場合、考えられるオプションの1つは、別の言語に変更することです。(もちろん、これは状況によってはオプションではない場合があります。)

于 2011-09-23T06:55:39.057 に答える
3

AFAIK整数は、C ++では符号の大きさとして表すことができます。その場合、符号拡張は0で埋められます。したがって、これに依存することはできません。

于 2011-09-22T22:53:09.047 に答える