Hairi
Hairi

Reputation: 3715

printf prints big number for uint_8

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

Answers (2)

Some programmer dude
Some programmer dude

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

Bathsheba
Bathsheba

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

Related Questions