"Q"
actually is a character array of two characters: { 'Q', '\0' }
(null-terminated C-string of length 1), residing at some specific address in memory.
Arrays, explicitly defined or coming from string literals doesn't matter, decay to pointers automatically in most contexts, e. g. when passing as function arguments, dereferencing them, … – and especially, too, when applying a cast to them!
So what happens here is actually equivalent to
char const* ptr = "Q";
char(ptr);
Actually, this is undefined behaviour, as char
, be it signed or not, is not large enough to hold a pointer value, so anything could happen. Under the hoods, the code will most likely be treated as if you (fully legally) did:
char(unsigned char(uintptr_t(ptr)))
simply cutting off the most significant three bytes.
What remains is the least significant byte of the memory address, and it's just pure accident that it matches 99, the ASCII value of c
, it could have been any value else.