1

printf gives me weird extra values in some cases. What might be happening?

I'm manipulating values in an uint8_t array and printing it out to my terminal to verify if everything is correct. But for some reason I am getting weird values when I print a uint8_t - I get the expected value plus some other value (it is always the same extra value), as if I was printing a uint16_t or other 16bit value. I trimmed it all down to the following example:

This is the test code

test_payload[0] = (uint8_t)0x58;
test_payload[1] = (uint8_t)0x7B;
test_payload[2] = (uint8_t)0x6B;
test_payload[3] = (uint8_t)0x05;
test_payload[4] = (uint8_t)0x4F;
test_payload[5] = (uint8_t)0x81;
test_payload[6] = (uint8_t)0x69;
test_payload[7] = (uint8_t)0x00;

printf("%x\n\r", test_payload[0]);
printf("%x\n\r", test_payload[1]);
printf("%x\n\r", test_payload[0] + test_payload[1]);

for(i = 0; i < 8; i++)
{
    printf("%x", test_payload[i]);
}

The output I get is

5803
7b03
d3
58037b0333034f03810369033

What is making it behave like that?

caiomarcos
  • 13
  • 3

2 Answers2

2

%x requires an unsigned int as parameter; If you want to print a single byte, e.g. as uint8_t, you need to write %hhx.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • 1
    `uint8_t` arguments are promoted to `int` when passed to `printf` which should work fine for a `%x` conversion specification. – chqrlie Jul 07 '19 at 16:28
  • I tried this too and apparelty the compiler does not support it, I got a bunch of "hx" on the terminal. – caiomarcos Jul 08 '19 at 13:28
2

The first code fragment should produce 58, but you do not output a newline, so any subsequent output will appear right after the 58. It is possible that you output 86 in the code that follows the fragment. Post a complete program that exhibits the offending behavior, or change the format as %x\n to separate 58 from subsequent output.

Technically, printf expects an unsigned int argument for a %x conversion format, but an int value should work fine and test_payload[0] is promoted to int and passed as such to printf. You could try changing the format to %hhx or casting the argument as (unsigned int)test_payload[0], but it would be very surprising that one of these changes alone fix the problem.

EDIT: from your extra information, it looks like the compiler for your embedded target is very peculiar. Definitely try casting the arguments as in

printf("%x\r\n", (unsigned int)test_payload[0]);

Observing that printf("%x\n\r", test_payload[0] + test_payload[1]); seems to work fine, the problem is not passing an int instead of an unsigned int, which would have been bad enough... It seems printf() passes uint8_t values incorrectly, in a non conforming way.

Another potential source of problems is if you forgot to include <stdio.h> and are calling printf without a definition with a prototype. The C Standard (6.5.2.2 Function calls) explicitly defines this call as having undefined behavior if the function is defined (in the library) with a prototype that includes an ellipsis (...).

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • That's the code right there. After it the microcontroller starts readings sensors and such, not printing anything in the nex few minutes. Also, if I make a while() loop to print the 8 values from the test_payload array, I get that 86 after each non-zero value. I'll put this into the question to give a better example. – caiomarcos Jul 07 '19 at 16:39
  • Yes, just did the (unsigned int) cast and it worked. Realized it was a compiler thing and updated the question. Weird indeed, thanks. – caiomarcos Jul 07 '19 at 16:59