5

重複の可能性:
64ビットシフトの問題

私はWindows864ビットでVisualStudio2012を使用しており、AMD PhenomIIを使用してデバッグモードでx64をターゲットにしています。
だから基本的に...

uint64_t Foo = 0xFFFFFFFFFFFFFFFF << 64;//Foo is now 0x0000000000000000
uint64_t Derp = 64;
uint64_t Bar = 0xFFFFFFFFFFFFFFFF << Derp;//Foo is now 0xFFFFFFFFFFFFFFFF

63などの低い値を使用すると、通常の動作が復元されます。
なぜこれが起こっているのですか、どうすれば回避できますか?

更新:リリースモードに切り替えました。見よ、問題は消え、両方とも0を返しました。しかし、問題はデバッグモードのままであり、コードをデバッグするために必要な場所です。

4

2 に答える 2

7

ビット幅以上の値でシフトする場合、シフト操作は未定義の動作をします。

C++11 ドラフトのセクション 5.8 p1 から:

オペランドは、整数型またはスコープなしの列挙型である必要があり、整数昇格が実行されます。結果の型は、昇格された左オペランドの型です。右オペランドが負の場合、またはプロモートされた左オペランドのビット長以上の場合、動作は未定義です。

于 2012-08-05T14:59:47.317 に答える
4

整数のサイズ以上のシフトは C++ では定義されていないと思います。

最初の例は、定数のみを含むため、コンパイル時に評価されています。2 番目の例は、プロセッサによって実行時に計算されます。

シフトを 2 つの部分に分割できます。

uint64_t Bar = 0xFFFFFFFFFFFFFFFF << (Derp / 2);
Bar <<= Derp - (Derp / 2);
于 2012-08-05T14:58:17.823 に答える