I have this sample code which generates the following warning (VS2008 compiler with SP1):
warning C4146: unary minus operator applied to unsigned type, result still unsigned
Code:
void f(int n)
{
}
int main()
{
unsigned int n1 = 9;
f(-n1);
}
But since function f
is taking it's parameter as an int
shouldn't this code compile without any warnings?
if x
is of type unsigned int
, then so is -x
and it is virtually equivalent to 2n-x
(where n
is most likely 32). To avoid the warning and get correct behavior, cast to int
:
f(-static_cast<int>(n));
I would recommend reading the "Expressions" chapter of the C++ standard. There you'll see that in the expression -x
integral promotions take place on x
, which means that almost anything gets promoted to int
, but unsigned int
is not.
Look at this very interesting example:
template<class T>
void f(T x)
{
//somehow print type info about x, e.g. cout << typeid(x).name() or something
}
int main()
{
char x;
f(x);
f(+x);
f(-x);
}
prints:
char
int
int
But char
-> int
is an integral promotion, whereas unsigned int
-> int
is a conversion
Standard 5.3.1/7
The operand of the unary - operator shall have arithmetic or enumeration type and the result is the negation of its operand. Integral promotion is performed on integral or enumeration operands. The negative of an unsigned quantity is computed by subtracting its value from 2n, where n is the number of bits in the promoted operand. The type of the result is the type of the promoted operand.
And the paragraph on Integral Promotion 4.5/1
An rvalue of type char, signed char, unsigned char, short int, or unsigned short int can be converted to an rvalue of type int if int can represent all the values of the source type; otherwise, the source rvalue can be converted to an rvalue of type unsigned int.
i.e. an unsigned int will not be promoted to an int.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With