Fei Xue
Fei Xue

Reputation: 2045

What does this mean? (int &)a

define a float variable a, convert a to float & and int &, what does this mean? After the converting , a is a reference of itself? And why the two result is different?

#include <iostream>
using namespace std;
int
main(void)
{
    float a = 1.0;
    cout << (float &)a <<endl;
    cout << (int &)a << endl;

    return 0;
}


thinkpad ~ # ./a.out 
1
1065353216

Upvotes: 5

Views: 2686

Answers (3)

James Kanze
James Kanze

Reputation: 154047

It means undefined behavior:-).

Seriously, it is a form of type punning. a is a float, but a is also a block of memory (typically four bytes) with bits in it. (float&)a means to treat that block of memory as if it were a float (in other words, what it actually is); (int&)a means to treat it as an int. Formally, accessing an object (such as a) through an lvalue expression with a type other than the actual type of the object is undefined behavior, unless the type is a character type. Practically, if the two types have the same size, I would expect the results to be a reinterpretation of the bit pattern.

In the case of a float, the bit pattern contains bits for the sign, an exponent and a mantissa. Typically, the exponent will use some excess-n notation, and only 0.0 will have 0 as an exponent. (Some representations, including the one used on PCs, will not store the high order bit of the mantissa, since in a normalized form in base 2, it must always be 1. In such cases, the stored mantissa for 1.0 will have all bits 0.) Also typically (and I don't know of any exceptions here), the exponent will be stored in the high order bits. The result is when you "type pun" a floating point value to a an integer of the same size, the value will be fairly large, regardless of the floating point value.

Upvotes: 9

Corbin
Corbin

Reputation: 33467

cout << (float &)a <<endl;
cout << (int &)a << endl;

The first one treats the bits in a like it's a float. The second one treats the bits in a like it's an int. The bits for float 1.0 just happen to be the bits for integer 1065353216.

It's basically the equivalent of:

float a = 1.0;
int* b = (int*) &a;
cout << a << endl;
cout << *b << endl;

(int &) a casts a to a reference to an integer. In other words, an integer reference to a. (Which, as I said, treats the contents of a as an integer.)

Edit: I'm looking around now to see if this is valid. I suspect that it's not. It's depends on the type being less than or equal to the actual size.

Upvotes: 15

Matthew Walton
Matthew Walton

Reputation: 9979

The values are different because interpreting a float as an int & (reference to int) throws the doors wide open. a is not an int, so pretty much anything could actually happen when you do that. As it happens, looking at that float like it's an int gives you 1065353216, but depending on the underlying machine architecture it could be 42 or an elephant in a pink tutu or even crash.

Note that this is not the same as casting to an int, which understands how to convert from float to int. Casting to int & just looks at bits in memory without understanding what the original meaning is.

Upvotes: 2

Related Questions