Питання двояке: По-перше, це
char c = CHAR_MAX;
c += 1;
оцінюється інакше від
char c = CHAR_MAX;
c = c + 1;
а відповідь - ні, це не так , тому що C11 / C18 6.5.16.2p3 :
- Складене присвоєння форми
E1 op = E2
еквівалентне простому вираженню присвоєння, E1 = E1 op (E2)
за винятком того, що значення значення E1
оцінюється лише один раз, а щодо невизначено послідовного виклику функції операція складеного призначення є єдиною оцінкою. Якщо E1
має атомний тип, складене призначення - це операція читання-зміна-запис із memory_order_seq_cst
семантикою порядку пам'яті. 113)
Потім, питання в тому, що відбувається в 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
буде переведений на an int
, і CHAR_MAX == INT_MAX
=> CHAR_MAX + 1
викличе ціле переповнення і поведінка буде невизначена .
Тобто можливими результатами є:
Якщо char
це непідписаний цілочисельний тип, результат завжди є 0
, тобто CHAR_MIN
.
В іншому випадку char
це підписаний цілочисельний тип, а поведінка визначено / не визначено:
CHAR_MIN
або якесь інше значення, визначене реалізацією,
- піднімається визначений реалізацією сигнал, можливо, припиняючи програму,
- або поведінка не визначена на деяких платформах, де
sizeof (char) == sizeof (int)
.
Всі операції інкремента c = c + 1
, c += 1
, c++
і ++c
мають ті ж побічні ефекти на тій же платформі. Оцінене значення виразу c++
буде значенням c
до збільшення; для інших трьох це буде значення c
після приросту.