7

I casted the memory address from double to an integer . Even though they point to the same address why the values are different ?

#include<iostream>
using namespace std;

int main()
{
    double d = 2.5;
    auto p = (int*)&d;
    auto q = &d;
    cout<<p<<endl; // prints memory address 0x7fff5fbff660
    cout<<q<<endl; // print memory address  0x7fff5fbff660
    cout<<*p<<endl; //prints 0
    cout<<*q<<endl; // prints 2.5
    return 0;

}

But why the value are different

0x7fff5fbff660
0x7fff5fbff660
0
2.5
Program ended with exit code: 0
Hariom Singh
  • 3,512
  • 6
  • 28
  • 52

6 Answers6

10

Suppose you have "11" written on a piece of paper. That is eleven if it's decimal digits. That is two if there's one mark for each value. That's three if it's binary. How you interpret stored information affects the value you understand it to be storing.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
7

It's because you've violated the strict aliasing rule, giving you undefined behavior. You cannot acesss type A through a pointer of type B and just pretend it works.


TL;DR:

if you have an int* pointing to some memory containing an int and then you point a float* to that memory and use it as a float you break the rule. If your code does not respect this, then the compiler's optimizer will most likely break your code.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
7
double d = 2.5;
auto p = (int*)&d;
auto q = &d;

p and q are created pointing to the same memory location. The memory holds a double (usually 8 bytes)

When you create

auto p = (int*)&d;

you are telling the compiler ( reintepret_cast< int*> ( &d) ) that the value in d was an integer.

So the values of the pointers are the same, but the types are not.

When you print out

cout<<*q<<endl; // prints 2.5

You are displaying the correct value - as it came in and out through that.

when you print out

cout<<*p<<endl; //prints 0

You are looking at 4 (typically) bytes of the 8 byte memory, and interpreting them as an integer.

These happen to be 0x00, 0x00, 0x00, 0x00

mksteve
  • 12,614
  • 3
  • 28
  • 50
3

The memory addresses are the same, and they both point to a double-precision floating point number in memory. However, you've asked the compiler to treat one as an integer and another as a double. (A pointer might just be a memory address, but at compile-time the compiler has information about the type as well.) It just so happens that the in-memory representation of this particular double-precision number looks like a 0 when treated as an integer.

struthersneil
  • 2,700
  • 10
  • 11
0

Because you have casted them to different types yourself.

Phil Krylov
  • 531
  • 4
  • 8
-2

When you do auto p = (int*)&d; you are asking the compiler to store a double value in a memory area allocated for an integer. An integer and a double are represented in different formats in a computer's memory. A double is stored using a floating point representation in memory, while an int is not. This is a classic example of undefined behaviour.

SCCC
  • 341
  • 3
  • 13
  • It would be good if you can explain the rationale behind the downvotes. – SCCC Jul 30 '17 at 22:39
  • 2
    "asking the compiler to store a double value in a memory area allocated for an integer" - wrong. This does not store a double. This statement does not store anything. The double is already there. The cast is a request to interpret that double as an int instead, which can lead to problems as described in other answers. – 1201ProgramAlarm Jul 31 '17 at 04:05