0

I have the followig code and I want to know why I have the following output:

#include <iostream>

int main() {
    double nValue = 5;
    void *pVoid = &nValue;

    short *pInt = static_cast<short*>(pVoid);

    std::cout << *pInt << std::endl; 
    return 0;
}

And it outputs me '0'. I want to know why is this happening. Thank you!

  • C lets you break the rules and you get weird stuff. Its only predictable what happens on a given compiler and hardware and maybe not even then. Depends. It lets you break the rules because of a philosophy that says you might know what you are doing and so it gives you plenty of rope with which to hang yourself. – Lee Meador May 17 '13 at 17:27
  • My question would be, what were you expecting the output to be? `5`?? – John Dibling May 17 '13 at 18:01

5 Answers5

1

You have UB (Undefined Behaviour), as you're violating pointer aliasing rules. This means anything can happen.

For example, the compiler has all rights to expect a short* will never refer to a double object, so it can pretty much interpret *pInt however it wants.

Or it's possible that the compiler interprets the code literally, and it just so happens that on your platform, the binary representation of 5.0 starts with two (or sizeof(short)) bytes of zeroes.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
0

You are casting memory block with double data to short. Since you store a small value in that block it is not stored in first bits. Thus first bits are zero. But it rely on internal double representation and short size, so it is not guaranteed to be the same on different platforms

Andrew
  • 24,218
  • 13
  • 61
  • 90
0

You're trying to interpret the contents of a double as a short. This invokes undefined behavior - your program is free to do anything.

  • You are correct, but I don't think the behavior is undefined. It interprets the bits in the memory as a short, no matter what. Which happens to be zero in this case. Undefined behaviour is typically when the programming standard etc doesent speciy what is going to happen. – Henrik Kjus Alstad May 17 '13 at 17:30
  • @HenrikKjusAlstad And here, does it? –  May 17 '13 at 17:32
  • I'm not sure, you might be right. But the void pointer really just point at a memory address. Casting a void pointer to a short just tells the compiler to interpret whatever is there as a short. I don't see any reason why it should be undefined. Although I might be wrong – Henrik Kjus Alstad May 17 '13 at 17:39
  • 1
    @HenrikKjusAlstad [There are alignment and aliasing rules](http://stackoverflow.com/questions/6320789/c-aliasing-rules). –  May 17 '13 at 17:41
0

pVoid points to a bit pattern that represents a double. The type information is lost for the compiler once you use a void*. When casting the void* to short*, you claim that that the bit pattern pointed to is a short, which it isn't. The representation of a short and a double in memory are completely different. When you dereference pInt, the memory at that location happens to be 0. The compiler no longer knows at this point that the value's type is really double, so no implicit conversion is possible, if that's what you were expecting.

Dabbler
  • 9,733
  • 5
  • 41
  • 64
0

Just for fun, most probably the double representation of 5 on your machine is this

                *double  = (5)
0000000000000000000000000000000000000000000000000000000000000101
^^^^^^^^^^^^^^^^
   *short = (0)

This should show you why this is happeneing

int main() {
    double nValue = 5;
    short nValue_short = 5;

    std::bitset<sizeof(double)*8> bit_double(nValue);
    std::bitset<sizeof(short)*8> bit_short(nValue_short);

    std::cout << bit_double << std::endl; 
    std::cout << bit_short << std::endl; 
    return 0;
}
stardust
  • 5,918
  • 1
  • 18
  • 20
  • It this have to do with my architecture ? I mean, if my architecture were Big Endian instead of Little Endian, the output would've been also 5 ? – Mardaloescu Serban May 17 '13 at 17:38
  • That is of course not AT ALL what a double of value 5.0 actually looks like. And no, you would not get 5 no matter what endianness the system has - but on a little endian machine, we can expect the lower value bits of a small integer value to be a lot of zeros. [Lower value bits will be first on a little endian machine, and last on a big endian machine]. – Mats Petersson May 17 '13 at 17:41