/* printing-bytes.c Jeff Ondich, 23 Jan 2022 An exploration of the arduous business of printing a single byte as a two-digit hexadecimal number. C's automatic typecasting causes surprising problems. */ #include int main(int argc, char *argv[]) { // Various ways of printing a char's value in hexadecimal. At no time // do the bits in the relevant byte change, but several of these // printing options give us an answer we don't want. // // printf expects an int for %x. If it sees something that isn't // already an int (e.g. a char), printf does typecasting to transform the // argument to an int. And when a char gets typecast to an int, the // additional 24 bits get filled with whatever the leftmost bit of the // char is. So if the leftmost bit of the char is 1, then the int ends up as // a negative number, and in hex that looks like 0xFFFFFF?? where // the ?? is the contents of the original char. char ch = 0xc3; int n = (int)ch; printf("0x%x\n", n); printf("0x%x\n", ch); printf("0x%x\n", (unsigned char)ch); // yay! this one does what we want! printf("0x%x\n", (unsigned int)ch); printf("0x%x\n", ch & 0xFF); // yay! this one too! // Stay tuned. We're going to look at the assembly generated by this // program to figure out why the heck it works this way. return 0; }