The question is twofold: Firstly, is
char c = CHAR_MAX;
c += 1;
evaluated differently from
char c = CHAR_MAX;
c = c + 1;
and the answer is no it is not, because C11/C18 6.5.16.2p3:
- A compound assignment of the form
E1 op = E2
is equivalent to the simple assignment expression E1 = E1 op (E2)
except that the lvalue E1
is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. If E1
has an atomic type, compound assignment is a read-modify-write operation with memory_order_seq_cst
memory order semantics. 113)
Then, the question is what happens in c = c + 1
. Here the operands to +
undergo usual arithmetic conversions, and c
and 1
are therefore promoted to int
, unless a really wacky architecture requires that char
is promoted to unsigned int
. The calculation of +
is then evaluated, and the result, of type int
/unsigned int
is converted back to char
and stored in c
.
There are 3 implementation-defined ways in which this can then be evaluated:
CHAR_MIN
is 0 and therefore char
is unsigned.
Either char
is then promoted to int
or unsigned int
and if it is promoted to an int
, then CHAR_MAX + 1
will necessarily fit into an int
too, and will not overflow, or if unsigned int
it may fit or wrap around to zero. When the resulting value, which is numerically either CHAR_MAX + 1
or 0
after modulo reduction, back to c
, after modulo reduction it will become 0, i.e. CHAR_MIN
Otherwise char
is signed, then if CHAR_MAX
is smaller than INT_MAX
, the result of CHAR_MAX + 1
will fit an int
, and the standard C11/C18 6.3.1.3p3 applies to the conversion that happens upon assignment:
- Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
Or, iff sizeof (int) == 1
and char
is signed, then char
is promoted to an int
, and CHAR_MAX == INT_MAX
=> CHAR_MAX + 1
will cause an integer overflow and the behaviour will be undefined.
I.e. the possible results are:
If char
is an unsigned integer type, the result is always 0
, i.e. CHAR_MIN
.
Otherwise char
is a signed integer type, and the behaviour is implementation-defined/undefined:
CHAR_MIN
or some other implementation-defined value,
- an implementation-defined signal is raised, possibly terminating the program,
- or the behaviour is undefined on some platforms where
sizeof (char) == sizeof (int)
.
All increment operations c = c + 1
, c += 1
, c++
and ++c
have the same side effects on the same platform. The evaluated value of the expression c++
will be the value of c
before the increment; for the other three, it will be the value of c
after the increment.