5u is a single token, an rvalue expression of type unsigned int . Unary operator - applied to it in accordance with the rules of unsigned arithmetic (arithmetic modulo 2 ^ n, where n is the number of bits in an unsigned type). Results are converted to unsigned short ; if they are not fit (and they will not, if sizeof(int) > sizeof(short) ), the conversion will be performed modulo arithmetic (modulo 2 ^ n, where n is the number of bits in the target type).
It may be worth noting that if the original argument is unsigned short , the actual steps are different (although the results will always be the same). Thus, if you would write:
unsigned short k = 5; unsigned short b = -k;
The first operation will depend on the size of the short. If the shorts are smaller than ints (often, but not always), the first step would be to advance k to int . (If the sizes of short and int are identical, then the first step would be to advance k to unsigned int ; since then everything happens as described above.) Unary - will be applied to this int , according to the rule of signed integer arithmetic (thus, leading to the value -5). the result of -5 will be implicitly converted to unsigned short using modulo arithmetic as described above.
In general, these differences do not matter, but in cases where you can have the integral value INT_MIN , they could; for 2 additions of machines, -i , where i is of type int , and the value of INT_MIN is an implementation and may lead to strange values โโduring subsequent conversion to unsigned.
source share