I would like to store an unsigned char
into a char
by means of a shift. As the two data types have the same length (1 byte on my machine), I would have expected the following code to work:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main () {
printf ("%d\n", sizeof(char));
printf ("%d\n", sizeof(unsigned char));
unsigned char test = 49;
char testchar = (char) (test - 127);
printf ("%x\n", testchar);
return 0;
}
but it doesn't. In particular, I got the following output:
1
1
ffffffb2
that suggests that the char has been casted to int
. Does anybody has an explanation and, hopefully, a solution?
Because char does not have to be signed. Whether char is signed or unsigned is implementation-dependent. Some implementations make char signed, others make it unsigned. As such, there's no guarantee that (char) (test - 127) will produce a value that can be represented by char. C++ (14) does allow lossless conversion between unsigned char and char.
char is the most basic data type in C. It stores a single character and requires a single byte of memory in almost all compilers. unsigned char is a character datatype where the variable consumes all the 8 bits of the memory and there is no sign bit (which is there in signed char).
If you are just trying to squeeze data into a function which requires an unsigned char, simply cast uchar ch = (uchar)x (but, of course, beware of what happens if your int is too big). Specific endian: Use this when your destination requires a specific format.
It stores a single character and requires a single byte of memory in almost all compilers. unsigned char is a character datatype where the variable consumes all the 8 bits of the memory and there is no sign bit (which is there in signed char). So it means that the range of unsigned char data type ranges from 0 to 255.
%x
is a specifier for a 4-byte int
. To print one byte char
use %hhx
.
printf
typecasts its arguments according to the format specifiers passed to it.That is why testchar
was type promoted to int
.
printf is a variable argument function, and as such it's arguments are subject to default promotion rules. For this case, your char is promoted to an int, and in that process is sign extended.
A 2's complement int of 4 bytes with the binary pattern 0xffffffb2 is -78. Print it as a char with the %hhx
specifier.
See also Which integral promotions do take place when printing a char?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With