A Word of Warning
Casting a a pointer to int*
that wasn’t derived from an int*
is undefined behavior, and the compiler is allowed to do literally anything. This isn’t just theoretical: on some workstations I’ve coded on, an int*
must be aligned on a four-byte boundary, whereas a char*
might not be, trying to load a misaligned 32-bit value would cause a CPU fault, and therefore code like this might or might not crash at runtime with a “bus error.”
Where 1684096032 Comes From
The compiler here is doing the “common-sense” thing for a desktop computer in 2019. It’s letting you “shoot yourself in the foot,” so to speak, by emitting a load instruction from the address you cast to int*
, no questions asked. What you get is the garbage that CPU instruction gives you.
What’s going on is that "Papa Dadi"
is stored as an array of bytes in memory, including the terminating zero byte. It’s equivalent to, {'P','a','p','a',' ','D','a','d', 'i', '\0'}
. ("Papa Dadi"
is just syntactic sugar. You could write it either way) These are stored as their ASCII values1 { 0x50, 0x61, 0x70, 0x61, 0x20, 0x44, 0x61, 0x64, 0x69, 0x00 }
.
You happen to be compiling on a machine with four-byte int
, so when you alias wicked
to the int* baboom
, baboom[0]
aliases bytes 0–3 of wicked
and baboom[1]
bytes 4–7. Therefore, on the implementation you tested, you happened to get back the bytes " Dad", or in Hex, 20 44 61 64.
Next, you happen to be compiling for a little-endian machine, so that gets loaded from memory in “back-words order,” 0x64614420
.
This has the decimal value 1684096032
.
What You Meant to Do
Based on your remarks:2
cout << (int)wicked[1];
1 Evidently you aren’t running on the sole exception, an IBM mainframe compiler. These still use EBCDIC by default.
2 The consensus here is never to write using namespace std;
. Personally, I learned to use <iostream.h>
and the C standard library long before namespace std
and I still prefer to omit std
for those, so you can tell my code by the block of commands like using std::cout;
.