問題は2つあります。最初に、
char c = CHAR_MAX;
c += 1;
異なる評価
char c = CHAR_MAX;
c = c + 1;
C11 / C18 6.5.16.2p3のため、答えは「いいえ」ではありません。
- フォームの複合代入は、左辺値が1回だけ評価されることを除いて
E1 op = E2
、単純な代入式と同等であり、不確定にシーケンスされた関数呼び出しに関して、複合代入の操作は単一の評価です。がアトミックタイプの場合、複合割り当てはメモリ順序のセマンティクスを持つ読み取り-変更-書き込み操作です。113)E1 = E1 op (E2)
E1
E1
memory_order_seq_cst
次に、問題はで何が起こるかですc = c + 1
。ここでは、オペランド+
の通常の算術変換を受け、c
そして1
そのために昇格されint
、本当に奇抜なアーキテクチャがその必要がない限り、char
に昇格されますunsigned int
。次に、の計算が+
評価され、タイプint
/の結果unsigned int
が変換されてにchar
保存されc
ます。
これを評価できる実装定義の方法は3つあります。
CHAR_MIN
は0なので、char
符号なしです。
どちらかchar
が次に、int
またはにunsigned int
昇格され、それがに昇格されたint
場合、CHAR_MAX + 1
必然的ににint
も適合し、オーバーフローしないか、またはunsigned int
ゼロに適合またはラップする可能性があります。数値的に、CHAR_MAX + 1
または0
モジュロ削減後の結果の値がに戻るとc
、モジュロ削減後に0になります。CHAR_MIN
それ以外の場合char
は署名され、次にCHAR_MAX
がより小さい場合INT_MAX
、の結果はCHAR_MAX + 1
に適合しint
、標準のC11 / C18 6.3.1.3p3が代入時に発生する変換に適用されます。
- そうでない場合、新しいタイプは署名され、値をそのタイプで表すことができません。結果は実装定義であるか、実装定義の信号が発生します。
または、IFF sizeof (int) == 1
と char
署名されているが、その後char
に昇格しint
、そしてCHAR_MAX == INT_MAX
=>はCHAR_MAX + 1
、整数オーバーフローが発生し、動作は不定となります。
つまり、可能な結果は次のとおりです。
すべてのインクリメント操作はc = c + 1
、c += 1
、c++
と++c
同じプラットフォーム上で同じ副作用を持っています。式の評価値は、増分前のc++
値c
になります。他の3つの場合はc
、増分後の値になります。