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 1065353开发者_如何学C216
! It is a big surprise to me! So what is the true meaning of (int&)
conversion?
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);
cout<<i<<endl;
cout<<j<<end;
Check your favorite C++ book on these kinds of casts.
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.
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...
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.
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.
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
cout<<i<<endl;
cout<<(*j)<<endl;
How to fix:
float b = 1.0f;
int i = (int) b;
int castedB = (int)b;//static_cast<int>(b);
int& j = castedB;
cout<<i<<endl;
cout<<j<<endl;
精彩评论