The behavior of this expression is well defined.
Constructs similar to x = x + 1
are allowed because x
isn't assigned a value until all other subexpressions are evaulated. The same applies in this case.
There is also no problem with -x
because the expression has unsigned type and thus has well defined wraparound behavior as opposed to overflowing.
Section 6.5.3.3p3 of the C standard regarding the unary -
operator states:
The result of the unary -
operator is the negative of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.
So since no promotion occurs the type remains unsigned
throughout the expression. Though not explicitly stated in the standard, -x
is effectively the same as 0 - x
.
For the specific case of INT_MIN
being passed to this function, it has type int
and is outside of the range of unsigned
, so it is converted when passed to the function. This results in the signed value -2,147,483,648 being converted to the unsigned value 2,147,483,648 (which in two's complement happen to have the same representation, i.e. 0x80000000). Then when -x
is evaluated, it wraps around resulting in 2,147,483,648.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…