In languages like C/C++, when we do:
char c = 'A';
We allocate memory to store number 65 in binary:
stuff_to_the_left_01000001_stuff_to_the_right
Then if we do:
int i = (int) c;
As I understand it, we’re saying to the compiler that it should interpret bit pattern layed out as stuff_to_the_left_01000001__00000000_00000000_00000000_stuff_to_the_right, which may or may not turn out to be 65.
The same happens when we perform a cast during an operation
cout << (int) c << endl;
In all of the above, I got ‘A’ for character and 65 in decimal. Am I being lucky or am I missing something fundamental?
Casts in C do not reinterpret anything. They are value conversions.
(int)cmeans take the value ofcand convert it toint, which is a no-op on essentially all systems. (The only way it could fail to be a no-op is if the range ofcharis larger than the range ofint, for example ifcharandintare both 32-bit butcharis unsigned.)If you want to reinterpret the representation (bit pattern) underlying a value, that value must first exist as an object (lvalue), not just the value of an expression (typically called “rvalue” though this language is not used in the C standard). Then you can do something like:
However, except in the case where
new_typeis a character type, this invokes undefined behavior by violating the aliasing rules. C++ has a sort of “reinterpret cast” to do this which can presumably avoid breaking aliasing rules, but as I’m not familiar with C++, I can’t provide you with good details on it.In your C++ example, the reason you get different results is operator overloading.
(int)'A'does not change the value or how it’s interpreted; rather, the expression having a different type causes a different overload of theoperator<<function to be called. In C, on the other hand,(int)'A'is always a no-op, because'A'has typeintto begin with in C.