0

Here's a simple code

unsigned char t = 0xFC; // this is 252 in decimal, and -4 if it is signed char.
printf("t: %d 0x%01X 0x%02X 0x%03X 0x%04X 0x%08X\n", t, t, t, t, t, t);
// expecting result: 
// t: 252 0xFC 0x00FC 0x000FC 0x000000FC 0x00000000000000FC
printf("(signed char)t: %d 0x%01X\n", 
                      (signed char)t,  
                      (signed char)t); // expecting result: -4 0xFC

but what it actually print out is:

t: 252 0xFC 0xFC 0x0FC 0x00FC 0x000000FC
(signed char)t: -4 0xFFFFFFFC

It seems that the compiler is treating 1 byte = 4 bits And that a singed char t is showing 0xFFFFFFFC when I ask for showing only 1 byte, what is going on?

user97662
  • 942
  • 1
  • 10
  • 29
  • 1
    Two hex digits correspond to one byte, so you're seeing 4 bytes getting printed, not 8. `signed char` got implicitly converted to `int`, see https://en.cppreference.com/w/cpp/language/variadic_arguments#Default_conversions – HolyBlackCat Nov 07 '21 at 09:59
  • 3
    When you pass an integer value of a type smaller than `int` to `printf` it will be implicitly *promoted* to `int`. Which is signed. And the promotion includes *sign extension*. – Some programmer dude Nov 07 '21 at 10:02
  • Please state the compiler version, settings and flags – Mahmoud Fayez Nov 07 '21 at 10:13
  • Did you check docummentation (e.g. https://en.cppreference.com/w/c/io/fprintf ) on for the correct format specifier to print a 8bit value, or signed char, or unsigned char? I think you want those with `"hh"`. – Yunnosch Nov 07 '21 at 10:34
  • 1
    *`and -4 if it is unsigned char`*?!?! That is, at best, one very confusing comment. If it's unsigned the value can't be negative. – Andrew Henle Nov 07 '21 at 11:19
  • You need to recycle your C books. The size of any variant of `char` is 1, not 2. – n. m. could be an AI Nov 08 '21 at 06:35
  • Does this answer your question? [Printing hexadecimal characters in C](https://stackoverflow.com/questions/8060170/printing-hexadecimal-characters-in-c) – phuclv Nov 08 '21 at 07:15
  • duplicates: [printf adds extra `FFFFFF` to hex print from a char array](https://stackoverflow.com/q/31090616/995714), [Why does printf not print out just one byte when printing hex?](https://stackoverflow.com/q/3555791/995714) – phuclv Nov 08 '21 at 07:17
  • You lie to printf and tell it that you are passing an `int` and then an `unsigned int` while you are in fact passing `signed char`. – Lundin Nov 08 '21 at 07:20

1 Answers1

0

There are multiple issues in your question.

1. Possible typo

unsigned char t = 0xFC; // this is 252 in decimal, and -4 if it is unsigned char.

Most probably "if it is unsigned" is a typo, because unsigned numbers don't have a sign.

2. Misinterpretation of width field

printf("t: %d 0x%04X\n", t, t); // expecting result: 252 0xFC

The "0x" is not part of the conversion, and you tell printf() to use at least 4 digits, filling up with zeroes. And so the actual output is correct:

t: 252 0x00FC

3. Additional unawareness of the system's width of int

printf("(signed char)t: %d 0x%04X\n", (signed char)t, (signed char)t); // expecting result: -4 0xFC ... Why is the (signed char)t has 8 bytes? should it be 2 bytes as mentioned in so many C text books?

Apparently you know about integer promotion, but you don't know the width on an int in your system, and it is 4 bytes. Books on standard C telling you that an int has just 2 bytes are so old, you should drop them.

Additionally you are mixing "byte" and "hex digit". A single hex digit is 4 bits wide, to cover the range from 0x0=0b0000 to 0xF=0b1111. A byte is commonly 8 bits wide. So, the hex value "FFFFFFFC" has 8 digits, but these give 4 bytes.

You tell printf() to use at least 4 digits, filling up with zeroes. Since the number to print has 8 digits, you get the correct output:

(signed char)t: -4 0xFFFFFFFC

the busybee
  • 10,755
  • 3
  • 13
  • 30
  • I edited my answer after I did more experiment. It is even more confusing now. Have you tired it on your computer? – user97662 Nov 08 '21 at 07:16
  • Please reread the documentation of `printf()` and see where your assumptions are wrong. Apparently you still don't understand it. -- BTW, please do **not** change the original code in the question as it renders answers meaningless, disregarding the effort put in it. If you have something new in the same issue, **add** it, please! When you have done this, notify me and I'll see what I can do. – the busybee Nov 08 '21 at 17:45
  • I figured it out. Apparently it was integer promotion that I forgot about. – user97662 Nov 10 '21 at 08:39