左のオペランドのビット長よりも大きくシフトすると、未定義の動作が呼び出されます。ドラフト C++ 標準セクション5.8
シフト演算子の段落1には次のように書かれています (強調鉱山):
オペランドは、整数型またはスコープなしの列挙型である必要があり、整数昇格が実行されます。結果の型は、昇格された左オペランドの型です。右オペランドが負の場合、またはプロモートされた左オペランドのビット長以上の場合、動作は未定義です。
シフト量がリテラルの場合、 と の両方がこのコードに対して警告を生成するgcc
可能性があることに注意してclang
ください。
cout << (b>> 100000) ;
またはb
がconstの場合、警告gcc
は次のとおりです。
warning: right shift count >= width of type [enabled by default]
MSalters が質問へのコメントで指摘しているように、これは未定義の動作であるため、この警告に頼ることさえできない場合があります。これは、用語と定義セクションの未定義の動作に関する標準の注記と一致しています。
注: [...] 許容される未定義の動作の範囲は、状況を完全に無視して予測できない結果をもたらすことから、変換中またはプログラム実行中に、環境に特有の文書化された方法で動作すること (診断メッセージの発行の有無にかかわらず) にまで及びます。変換または実行 (診断メッセージの発行を伴う)。[...]
プラットフォーム固有の詳細
サンプル コードに明らかなシフトがない理由として考えられるのは、一部のプラットフォームではシフト カウントがマスクされる5 bits
ためです。たとえばx86
、インテル® 64 および IA-32 アーキテクチャー ソフトウェア開発者マニュアルのセクションSAL/ SAR/SHL/SHR — IA-32 アーキテクチャ互換性セクションのシフトには次のように記載されています。
8086 はシフト カウントをマスクしません。ただし、他のすべての IA-32 プロセッサ (Intel 286 プロセッサ以降) は、シフト カウントを 5 ビットにマスクするため、最大カウントは 31 になります。[...]