1. ホーム
  2. c++

[解決済み] C++で符号付き整数のオーバーフローはまだ未定義ですか?

2023-05-15 14:41:35

質問

知っての通り 符号付き整数のオーバーフローは未定義の動作です。 . しかし、C++11 では興味深いことがあります。 cstdint のドキュメントを参照してください。

パディングビットがなく、それぞれ正確に8, 16, 32, 64ビットの幅を持つ符号付き整数型であり 負の値には 2 の補数を使用 (実装がこの型を直接サポートする場合のみ提供されます)

リンク参照

ここで質問です。 int8_t , int16_t , int32_tint64_t の負の数は2の補数ですが、これらの型のオーバーフローはやはり未定義の動作なのでしょうか?

編集 C++11とC11のStandardを確認したところ、以下のようなことがわかりました。

C++11, §18.4.1:

ヘッダは、C標準の7.20と同じように、すべての関数、型、マクロを定義しています。

C11, §7.20.1.1:

型付けされた名前 intN_t は幅N、パディングビットなし、2の補数表現の符号付き整数型を指定します。したがって int8_t はちょうど8ビットの幅を持つ符号付き整数型であることを表します。

どのように解決するのですか?

<ブロッククオート

は、これらの型のオーバーフローはまだ未定義の動作なのでしょうか?

はい、そうです。 C++11標準の5/4項(一般的なあらゆる式について)による。

式の評価中に、結果が数学的に定義されていない場合、または型の表現可能な範囲にない場合 表現可能な値の範囲内にない場合。 動作は未定義です。 . [...]

2 の補数表現がこれらの符号付き型に使用されるという事実は、これらの型の式を評価するときに 2^n の算術剰余金が使用されることを意味しません。

に関して 符号なし については、規格で明示的に規定されています(3.9.1/4項)。

宣言された符号なし整数 unsigned , は 2^n の算術法則に従わなければなりません。 ここでnは その特定のサイズの整数の値表現におけるビットの数です。

これは、符号なし算術演算の結果が常に"であることを意味します。 数学的に定義される であり、結果は常に表現可能な範囲にあるため、5/4は適用されません。脚注 46 でこれを説明しています。

46) これは次のことを意味しています。 無記名 算術はオーバーフローしません。 で表現できない結果は、unsigned integer typeで表現できる最大値より1つ大きい数で減数されるため、unsigned 算術はオーバーフローしないことを意味します。 というのは、unsigned整数型で表現できない結果は、unsigned整数型で表現できる最大の値より1つ大きい数だけ減少するからです。