This:
s += u;
Is the same as this:
s = s + u;
As per section 6.5.16.2p3 of the C standard:
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
So first s + u
is evaluated. This causes s
to be converted to type unsigned
as per the usual arithmetic conversions, and the result is unsigned. Then this result is assigned back to s
which undergoes a conversion from unsigned
to signed
.
So in this particular case:
signed s = INT_MAX;
unsigned u = 1;
s += u;
The value of s
is converted to unsigned
and 1 is added to it, resulting in an unsigned value of INT_MAX + 1
. This value is then converted to signed
, which undergoes an implementation defined conversion due to the value being out of range as per section 6.3.1.3p3:
1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new
type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that
can be represented in the new type until the value is in the range of
the new type.
3 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.
So the above does not have undefined behavior, but it does have implementation defined behavior.