Different isn't the same. Try this:
#include <cstdio>
#include <iostream>
int main() {
int i = '6';
char *ii = reinterpret_cast<char*>(&i);
std::printf("%c\n", *ii);
std::printf("%d\n", *ii);
std::cout << *ii << '\n';
std::cout << (int)*ii << '\n';
}
Initializing i to '6' is just a clarification.
In the calls to printf, the char value that *ii points to is promoted to int in the function call. Types smaller than int get promoted when they're arguments to the variable part of a function that takes a variable parameter list (such as printf).
The first printf statement prints the value of *ii as a character value; you'll get "6". The second prints it as an integer value; you'll get whatever value represents the character '6' (in ASCII that's 54, which is probably what you'll see).
The first insertion into std::cout inserts the char value; stream inserters are overloaded for integral types, so you get the inserter that takes an argument of type char, and it displays the character that the value represents, just like the first printf call.
The second insertion into std::cout inserts the integer value of *ii, just like the second call to printf.
charin C++ prints achar, i.e. the character the encoded value represents.*ii(in order to print it) gives undefined behaviour, in both C and C++ samples. There is no requirement that the value printed by what you assigned. The only difference is that a C++ compiler has to be forced to allow the initialisation of aii(i.e. using an explicit type conversion), but a C compiler does not. The net result is that there is no guarantee about what value your code prints, in either language.reinterpret_cast<int&>(*reinterpret_cast<char*>(&i))(Which is legal, aschar*is the object representation, and if it explicitly casted would be required to print54), and the second is just*reinterpret_cast<char*>(&i)(Which in this case the first byte is(char) 54, which as ASCII is'6'. On platforms with the opposite endianness, it would have printed the nul byte'\x00')