問題は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)E1E1memory_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、増分後の値になります。