uint32_t a = 10;
uint16_t b = 0;
if (a > b)
{
printf("a > b\n");
}
I was expecting that b would get promoted to int and the compiler would complain about comparing signed and unsigned.
But the compiler did not raise any warning.
When I change
if (a > b) to if (a > (b * 10)) the compiler says
warning: comparison between signed and unsigned
Why is this so?
And is it safe to typecast this to uint32_t?
if (a > (uint32_t)(b * 10))
If
intis 32 bits, sure. If not, then it isn't promoted.It is, on a 32 bit system.
It's not really the compilers job to keep track of that. If you get a warning, it's just a bonus. But also please note that in your example the conversion is done in two internal steps: first the integer promotions is performed on the
uint16_tmaking itint. But then immediately afterwards, the usual arithmetic conversions convert thatintto auint32_t. So essentially as far as the programmer is concerned, theuint16_tis converted touint32_tand that conversion is always safe.Generally, operations mixing unsigned operands of different sizes are safe.
bgets promoted tointand10is alreadyint. There's no way for the multiplication to overflow since it can't get larger than 655350. You can cast touint32_tafterwards if you like, but it doesn't rally achieve anything except being explicit.More rugged code would have done the cast before the multiplication or perhaps used
10uinstead. But in this specific case it really don't matter.