整数拡張とC++でのオーバーフローに頭を悩ませようとしています。私はいくつかの点で少し混乱しています:
a)次のコードセグメントがある場合:
int i = -15;
unsigned j = 10;
std::cout << i + j;
出-5 % UINT_MAX
ます。これは、式i + j
が自動的に符号なしにプロモートされるためですか?私は標準(4.13)を読み込もうとしていました:
— The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.
これを間違って読んでいるかどうかはわかりませんが、それが本当なら、なぜi + j
署名されていないのですか?
b)前のセグメントに追加すると、次のようになります。
int k = j + i;
それはに評価されてい-5
ます。式j + i
を最初に評価4294967291
して、システムに与え、それをjに設定するべきではありませんか?それは範囲外であるはずです、それでこの振る舞いは未定義ですか?なぜ私が得るのかわかりません-5
。
c)を使用してa)からセグメントを少し変更すると、次のようになりshort
ます。
short i = -15;
unsigned short j = 10;
std::cout << i + j;
これを実行すると、a)と同じ結果が得られると思いましたが、-5 % USHRT_MAX
。ただし、これを実行すると、が得られ-5
ます。short
使用すると、とは異なる値が得られるのはなぜint
ですか?
d)符号付き積分のオーバーフロー動作は未定義であることを常に学びました。例:int r = ++INT_MAX
未定義になります。
ただし、符号なしオーバーフローが発生した場合は、数量が定義されます。例:unsigned a = ++UINT_MAX
、の場合、aは。になります0
。あれは正しいですか?
しかし、規格はそれについて何も述べていないようでした。本当?もしそうなら、それはなぜですか?