0

I just have a quick question on the extraneous number (1684096032) outputted to the screen. I expected the integer ASCII value (97) to be outputted, as that is the ASCII value of lowercase 'a'. The console gave me a ginormous number instead...

using namespace std;

int main(){
    char dadum[50] = "Papa Dadi";
    char* wicked = dadum;
    int* baboom = (int*)wicked;
    cout << baboom[1] << endl;
    cout<<"Hello World";

    return 0;
}
Galik
  • 47,303
  • 4
  • 80
  • 117
j.doe
  • 121
  • 6
  • 1
    This isn't strictly a duplicate since there probably a reason you're getting the exact number you see, but have a look at https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule. – Mark Ransom Feb 23 '19 at 06:30
  • The ASCII Value of lowercase a ( typecasted to an integer) – j.doe Feb 23 '19 at 06:32

2 Answers2

3

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;.

Davislor
  • 14,674
  • 2
  • 34
  • 49
2

You are trying to print out the second value of integer array which points to the string "Papa Dadi"

You should know that the integer is 4-bytes and char is 1-byte. so each one element in the integer array will skip 4-bytes(characters) the print out you see is "0x64614420" in hex, which when you think about big-endian you will see the following

0x20 is space character.

0x44 is 'D'

0x61 is 'a'

0x64 is 'd'

so you need to convert big-endian to little-endian if you care about order. however I am not sure what are you trying to achieve.

Mahmoud Fayez
  • 3,398
  • 2
  • 19
  • 36