1

Right now I'm watching this lecture: https://www.youtube.com/watch?v=jTSvthW34GU In around 50th minute of the film he says that this code will return non-zero value:

float f = 7.0;
short s = *(short*)&f;

Correct me if I'm mistaking:

  1. &f is a pointer to float.
  2. We take &f and cast it to pointer to short.
  3. Then we dereference (don't know if it's a verb) that pointer so eventually the whole statement represents a value of 7.

If I print that it displays 0. Why?

JCob
  • 15
  • 2

3 Answers3

2

Dereferencing through a cast pointer does not cause a conversion to take place the way casting a value does. No bits are changed. So, while

float f = 7.0;
short s = (short)f;

will result in s having the integer value 7,

short s = *(short *)&f;

will simply copy the first 16 bits (depending on platform) of the floating point representation of the value 7.0 into the short. On my system, using little-endian IEEE-754, those bits are all zero, so the value is zero.

Lee Daniel Crocker
  • 12,682
  • 1
  • 28
  • 50
1

Floats are represented internally as 4byte floating point numbers (1 signal bit, 8 exponent bits, 23 mantissa bits) while shorts are 2byte integer types (two's compliment numbers). The code above will reinterpret the top two or bottom two bytes (depending on endianness) of the floating point number as an short integer.

So in the case of 7.0, the floating point number looks like:

0_1000000 1_1100000 00000000 00000000

So on some machines, it will take the bottom 2bytes (all 0s) and on others, it will take the top bytes (non-zero).

For more, see:

Floating-point: http://en.wikipedia.org/wiki/Floating_point

Endianness: http://en.wikipedia.org/wiki/Endianness

Unn
  • 4,259
  • 15
  • 29
  • Perhaps: Floats are represented internally as 4byte floating point numbers **in IEEE-754 single-precision floating point format** (1 signal bit, 8 exponent bits, 23 mantissa bits). Just for the sake of completeness and to provide makers for further research by any interested party. – David C. Rankin Nov 11 '14 at 21:17
0

Casting a pointer to a different type does not cause any conversion of the pointed-to value; you are just interpreting the pointed-to bytes through the "lens" of a different type.

In the general case, casting a pointer to a different pointer type causes undefined behavior. In this case that behavior happens to depend on your architecture.

To get a picture of what is going on, we can write a general function that will display the bits of an object given a pointer to it:

template <typename T>
void display_bits(T const * p)
{
    char const * c = reinterpret_cast<char const *>(p);

    for (int i = 0; i < sizeof(T); ++i) {
        unsigned char b = static_cast<unsigned char>(*(c++));

        for (int j = 0; j < 8; ++j) {
            std::cout << ((b & 0x80) ? '1' : '0');
            b <<= 1;
        }

        std::cout << ' ';
    }

    std::cout << std::endl;
}

If we run the following code, this will give you a good idea of what is going on:

int main() {
    float f = 7.0;
    display_bits(&f);
    display_bits(reinterpret_cast<short*>(&f));

    return 0;
}

The output on my system is:

00000000 00000000 11100000 01000000 
00000000 00000000 

The result you get should now be pretty clear, but again it depends on the compiler and/or architecture. For example, using the same representation for float but on a big-endian machine, the result would be quite different because the bytes in the float would be reversed. In that case the short* would be pointing at the bytes 01000000 11100000.

cdhowie
  • 144,362
  • 22
  • 272
  • 285
  • Note that in *all* cases such strict-alias violations cause undefined behavior (the conversion to `char*` as you've done is legal). It's just that sometimes it seems to do what you want. – Mark B Nov 11 '14 at 21:13
  • "casting a pointer to a different pointer type causes undefined behavior." - only if alignment requirements are not met – M.M Nov 11 '14 at 23:23