Reputation: 3715
Here is the code:
#include <stdio.h>
#include <stdint.h>
int main()
{
uint8_t ui8 = 0xff;
printf(" %x\n", ui8);
printf(" %x\n", (uint8_t)24);
printf(" %x\n", ui8 << (uint8_t)24);
}
The output is :
ff
18
ff000000
The question is: If I have two uint8_t
variables why the result is "promoted" to a higher rank. If it is not promoted, why do I get such a big number. I test it no MinGW win7-64bit platform
Upvotes: 0
Views: 598
Reputation: 409166
What happens is something called usual arithmetic conversion which leads to integer promotion for both arguments of the <<
operator.
If you instead of using the shift expression directly in the printf
argument, and instead stored it in a uint8_t
variable, then the result would be zero. However when you call printf
you would instead have a default argument promotion which would turn the uint8_t
variable into an int
. But that would lead to another problem because even though the format "%x"
expects an int
(an unsigned int
actually, see e.g. this printf
and family reference) the data is actually an uint8_t
. That means you have mismatched format specifier and argument, leading to undefined behavior. The correct format specifier to print an uint8_t
is "%hhx"
, or better yet use the PRI8x
macro:
uint8_t result = ...
printf("%" PRI8x "\n", result);
See e.g. this format macro reference.
Upvotes: 3
Reputation: 234685
Both arguments of <<
are converted to int
prior to the evaluation, despite the fact that you've attempted to force the issue with (uint8_t)24
.
This is necessarily true since uint8_t
is narrower than an int
on any platform.
So the result, ff000000
, you observe is consistent with an int
being at least 32 bits wide on your platform.
Upvotes: 3