What's the meaning of (int&) conversion in C++

float b = 1.0f;
int i = (int)b;
int& j = (int&)b;

cout << i << endl;
cout << j << end;

Then the output of i was 1, and the output of j was 1065353216! It is a big surprise to me! So what is the true meaning of (int&) conversion?

7 c++
13.10.2009 16:09:14

This is the problem with a C-style cast. You have to look closely to see what you're getting. In your case "(int)" was a normal static cast. The value is converted to an int via truncation. In your case "(int&)" was a reinterpret cast. The result is an lvalue that refers to the memory location of b but is treated as an int. It's actually a violation of the strict aliasing rules. So, don't be surprized if your code won't work anymore after turning on all optimizations.

Equivalent code with C++ style casts:

float b = 1.0f;
int i = static_cast<int>(b);
int& j = reinterpret_cast<int&>(b);

Check your favorite C++ book on these kinds of casts.

13.10.2009 16:13:12
Yes, It's a great answer. But I get one more question. Why an error, "error: invalid static_cast from type ‘float’ to type ‘int&’", happened when I used static_cast to cast a float to int& like "float b = 1.0f; int &j = static_cast<int&> b; ". I didn't find the limitations of static_cast in my favoraite C++ book, "The C++ Programming Language".
toby 14.10.2009 02:22:10
That's the protection you get from using C++ style casts. If the compiler accepts a static_cast chances are you're not doing anything wrong. The only unsafe things a static cast lets you do is an unchecked conversion from Base*/Base& to Derived*/Derived& and void* to T* as far as I can remember. It basically can invert implicit conversions, not more -- not counting const conversions.
sellibitze 14.10.2009 06:44:15

Seems like you are trying to create an int reference to a float by using (int&) cast. That will not work since floats are represented differently than int. This will not work.

If the representation of float and int are same then it might have worked.

13.10.2009 16:23:27
float b = 1.0f;
int& j = (int&)b;

In the second conversion, you're looking at the memory space that contains b as if it was a memory space that contains an int. Floating point values are stored in a manner that's completely different as integers, so the results are really different...

13.10.2009 16:23:54

In hexadecimal 1065353216 is 0x3F800000. If you interpret that as a 32-bit floating point number you get 1.0. If you write it out in binary you get this:

3    F    8    0    0    0    0    0
0011 1111 1000 0000 0000 0000 0000 0000

Or grouped differently:

0 01111111 00000000000000000000000
s eeeeeeee vvvvvvvvvvvvvvvvvvvvvvv

The first bit (s) is the sign bit, the next 8 bits (e) are the exponent, and the last 23 bits (v) are the significand. "The single precision binary floating-point exponent is encoded using an offset binary representation, with the zero offset being 127; also known as exponent bias in the IEEE 754 standard." Interpreting this you see that the sign is 0 (positive), the exponent is 0 (01111111b = 127, the "zero offset"), and the significand is 0. This gives you +00 which is 1.0.

Anyhow, what's happening is that you are taking a reference to a float (b) and reinterpreting it as an int reference (int&). So when you read the value of j you get the bits from b. Interpreted as a float those bits mean 1.0, but interpreted as an int those bits mean 1065353216.

For what it's worth, I have never used a cast using & like (int&). I would not expect to see this or use this in any normal C++ code.

13.10.2009 16:42:40
Hey, there is a typo here, (v) is repeated twice, fix the first (v) to (e).
legends2k 13.10.2009 16:30:57
I read the assembly code generated by g++. This is the exactly happening in the program.
toby 14.10.2009 02:28:33

In this particular case the conversion in question has no meaning. It is an attempt to reinterpret memory occupied by a float object and an int Lvalue. This is explicitly illegal in C/C++, meaning that it produces undefined behavior. Undefined behavior - that's the only meaning that it has in this case.

24.07.2012 18:50:32

What were you going to do? The same thing:

float b = 1.0f;
int i = (int) b;
int* j = (int*)b;//here we treat b as a pointer to an integer

How to fix:

float b = 1.0f;
int i = (int) b;
int castedB = (int)b;//static_cast<int>(b);
int& j = castedB;
13.10.2009 19:57:37