The relevant quote from the Standard is actually this:
(§5.3.1 / 8) The operand of a unary operator must have an arithmetic or non-enumerated type of enumeration, and the result is the negation of its operand. Integral promotion is performed on integral or enumerating operands. The negation of the unsigned value is calculated by subtracting its value from 2 n where n is the number of bits in the advanced operand. The result type is the type of the advanced operand.
(This is from C ++ 11, in older versions it was 5.3.1 / 7.)
So, -num will be evaluated as 2 CHAR_BIT * sizeof (num) - num (& ddagger;) . The result will be of the same type as the operand (after whole promotion), i.e. It will also be unsigned.
I just checked with GCC and it seems to have performed the operation exactly as described in the standard. I assume this is true for Visual C ++; otherwise it is a mistake.
(& ddagger;) This formula assumes that the corresponding number of bits corresponds to the size (in bits) of the variable in memory. As Keith Thompson points out in a comment, this cannot be true if there are padding bits (i.e. when not all bits are involved in representing a numerical value, which is possible in accordance with clause 9.1.1 / 1). In a system that uses more bits to store a value than is used to represent a numerical value, the formula will be inaccurate. (I personally do not know about any such system.)
source share