reinterpret_cast<> and where can it be used
Hi,
I am just reading about reinterpret_cast<> unfortunately I don't understand much other than what I have stated below:
reinterpret_cast allows any pointer to be converted into any other pointer type.
So when can this come in handy ?
I am really sorry my book doesn't speak about it, and I didn't quite understand the stuff I read on the internet.
I would appreciate any simple interpretation of reinterpret_cast and its use or any link that does that.
Thanks,
Muthu
Re: reinterpret_cast<> and where can it be used
Writing binary files:
Code:
ofstream file("myfile.dat", ios::binary);
int number = 20;
file.write(reinterpret_cast<const char*>(&number), sizeof(number));
Accessing the binary representation of floating point values:
Code:
int main()
{
float f = 1234.5678f;
const unsigned long* ptr = reinterpret_cast<const unsigned long*>(&f);
unsigned long bits = *ptr;
for (int i = 31; i >= 0; --i)
cout << ((bits & (1 << i)) ? 1 : 0);
return 0;
}
Are two uses that immediately come to mind.
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Muthuveerappan
Hi,
I am just reading about reinterpret_cast<> unfortunately I don't understand much other than what I have stated below:
reinterpret_cast allows any pointer to be converted into any other pointer type.
So when can this come in handy ?
I am really sorry my book doesn't speak about it, and I didn't quite understand the stuff I read on the internet.
I would appreciate any simple interpretation of reinterpret_cast and its use or any link that does that.
Thanks,
Muthu
reinterpret_cast is used to when you want to handle an object as if it was of a certain type, when it isn't. Also, it guarantees it will not modify your object during the cast.
Two examples I can find are:
Many c style functions return void pointers. You can't do much with those unless you reinterpret_cast into something useful. This is usually when you do allocations. I've never done this, but I know it exists.
Another example is if you want to see the binary representation of an object, like double:
Code:
int main(int argc, char *argv[])
{
double d = 31643.496844;
std::cout << d << std::endl;
std::cout << std::dec << static_cast<unsigned long long int>(d) << std::endl;
std::cout << std::hex << static_cast<unsigned long long int>(d) << std::endl;
std::cout << std::hex << reinterpret_cast<unsigned long long int&>(d) << std::endl;
system("PAUSE");
return EXIT_SUCCESS;
}
as you can see in this example, you can "read" into your double as if it was an unsigned long long int. Notice that if you do a static_cast, however, your double will be "transformed" into the corresponding unsigned long long int value.
You shouldn't ever do this in a real program though.
But to answer your question: "When can this come in handy". The answer is that unless your are writing a low level allocation program, or hardware controller, then never. It will never come in handy.
If you feel you want to use it to have several objects share the same memory space, then I would recommend you use an "union". But, again, this is really low level stuff.
Re: reinterpret_cast<> and where can it be used
reinterpret_cast<>() is used for casting between unrelated types. When you use this cast you are saying to your compiler, 'I know better than you do, I want you to reinterpret the bit pattern of this object as a different type'. In cases of multiple inheritance reinterpret_cast will never perform delta arithmetic.
Re: reinterpret_cast<> and where can it be used
thanks a lot for all your replies.
I have a few doubts:
------------------------
1) In Speedo's 2nd program, I couldn't understand the following line:
Code:
cout << ((bits & (1 << i)) ? 1 : 0);
a) I think "1 << i" means "1 * pow(2, i)", correct me if I am wrong.
b) what is the role of "&" in that statement ?
c) I think it is like an if else statement, and "(bits & (1 << i)" is evaluated like a boolean expression.
If that evaluates to true, then 1 is returned, else 0.
------------------------
2) In Monarch_dodra's program, I couldn't understand why we have long specified twice in each casting ?
Quote:
Originally Posted by
monarch_dodra
as you can see in this example, you can "read" into your double as if it was an unsigned long long int. Notice that if you do a static_cast, however, your double will be "transformed" into the corresponding unsigned long long int value.
3) I didn't understand that quote, Did that mean that always reinterpret_cast allows only cast by reference / or by pointers while static_cast allows only casting by reference / pointers for related types and for integral types it only allows casting by value?
My understanding is given below:
Code:
casting type Integral Types Other Types
---------------- ------------------- -----------------
reinterpret_cast only cast by reference / or by pointers only cast by reference / or by pointers
static_cast only cast by value cast by reference / or by pointers / value (provided the types are related)
------------------------
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Muthuveerappan
In Monarch_dodra's program, I couldn't understand why we have long specified twice in each casting ?
"long int" is a datatype. "long long int" is another (not 100% standard) datatype.
I recommend you read this.
http://home.att.net/~jackklein/c/inttypes.html
Re: reinterpret_cast<> and where can it be used
Thanks monarch_dodra and others.
I think I still have some confusion and unanswered questions. It would be great if someone could answer the questions posted previously. Thanks again.
Re: reinterpret_cast<> and where can it be used
Quote:
In Speedo's 2nd program, I couldn't understand the following line:
Code:
cout << ((bits & (1 << i)) ? 1 : 0);
From the inside out:
1 << i
Left shift the value 1 by i bits. The result will be equivilient to 1 * 2^i
bits & (1 << i)
Do a bitwise AND of bits and result of (1 << i). The value of (1 << i) is always going to have a single bit set (in binary its values will be: 1, 10, 100, 100, 1000, and so on), and the bitwise and will tell us whether or not that particular bit is set int the value bits.
(bits & (1 << i)) ? 1 : 0
Just prints out either a 1 or 0 depending on whether or not the bit in question is set - a nonzero value returned from the bitwise AND means that the bit is set.
Re: reinterpret_cast<> and where can it be used
Thanks a lot Speedo, for the prompt response.
I think I understand a little better, let me do some work on this and this will come back.
Thanks all.
Re: reinterpret_cast<> and where can it be used
Quote:
Many c style functions return void pointers. You can't do much with those unless you reinterpret_cast into something useful. This is usually when you do allocations. I've never done this, but I know it exists.
It's not correct you can perform cast to and from void* by using static_cast, reinterpret_cast is redundant here.
Just as complement:
Muthuveerappan, you should follow a simple rule: Don't use reinterpret_cast anywhere until you really need it. reinterpret_cast is very useful when you work with byte sequences(e.g decode protocol's messages) and it is a very harmful thing in high level programming.
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
ixSci
It's not correct you can perform cast to and from void* by using static_cast, reinterpret_cast is redundant here.
Thanks for clearing that up. As I said, it is something I have never done before, so I wasn't 100% sure. That, and I've never used the reinterpret_cast either so...
Re: reinterpret_cast<> and where can it be used
Thanks again to everyone, I think I understand a lil better.
reinterpret_cast preserves the bit pattern after conversion while static_cast doesn't, given below is an example:
Code:
#include <iostream>
using std :: cout;
using std :: endl;
using std :: cin;
void printInBinary(const unsigned int pDecimalNumber);
int main()
{
unsigned int decimalNumber;
system("clear");
cout << "enter the decimal number : ";
cin >> decimalNumber;
cout << "decimalNumber = ";
printInBinary(decimalNumber);
bool boolean1 = static_cast<bool>(decimalNumber);
cout << "using static_cast<bool> = ";
printInBinary(boolean1);
bool boolean2 = reinterpret_cast<bool&>(decimalNumber);
cout << "using reinterpret_cast<bool&> = ";
printInBinary(boolean2);
cout << endl;
return(0);
}
void printInBinary(const unsigned int pDecimalNumber)
{
const unsigned int SIZE_OF_TYPE_IN_BITS = sizeof(pDecimalNumber) * 8;
for(int index = SIZE_OF_TYPE_IN_BITS - 1; index >= 0; index --)
{
const unsigned short int BIT = (pDecimalNumber >> index) & 1;
cout << BIT;
}
cout << endl;
}
Re: reinterpret_cast<> and where can it be used
Quote:
reinterpret_cast preserves the bit pattern after conversion while static_cast doesn't, given below is an example:
Consider the subject from this viewpoint.
double d (35.25);
int i;
i = d;
In this case, while the compiler will generate a warning, it will perform a conversion. A few steps are 'automatically' generated to turn a double into an integer. This is a "value = value" scenario. The same thing applies with
i = static_cast<int>( d );
..a conversion is performed, but the compiler's warning should be set aside because you've informed it of your intention to perform this cast.
i = reinterpret_cast<int>( d );
The compiler won't perform this case, because it doesn't work on values.
int * ip = &i;
double *dp = &d;
ip = dp;
This would cause a compiler error, the pointers are incompatible. "Under the hood" all pointers are the same, a simple location in RAM. The type involved, however, has several implications to C++, and in more complex types there can be pointer adjustments required.
ip = static_cast<int *>( dp );
The compiler will refuse this conversion because the types aren't related. The compiler "knows" this conversion results in nonsense (the bits comprising the double have no useful meaning when interpreted as an integer, they require conversion to make sense).
A C style cast doesn't perform this check, and permits the cast....
ip = (int *) dp;
In this case, the C style cast makes no judgment about the relationship between the two pointers. C doesn't include the intelligence instilled into static_cast (or dynamic_cast), and simply stops all complaints or checking, at gives you...nonsense from the result of this line of code.
The closest we have to this in the new casting operators is reinterpret_cast.
ip = reinterpret_cast<int *>( dp );
This essentially duplicates the non-intelligent behavior of the C style cast, but gives us the syntax benefits of a C++ style cast.
Otherwise, the unintelligent nature of the C style cast is useful when casts otherwise make no sense, but we know from other contexts beyond the "sense" of the compiler that the cast is useful.
We use this unintelligent casting from structures created with similar features from C Code (or interfaces to it) into something useful, or other situations where the type system of C++ gets in the way, because the origins of the data being acted upon were created outside the C++ type awareness.
It's fire to play with, and not generally all that useful. If there's any way around it, use that instead. If the only way to perform a cast would cause the compiler to complain, and you know it's complaint isn't valid (and you need to really understand just why), then either a C style cast or the reinterpret_cast are appropriate (though the C style cast doesn't offer a good search/replace text benefit - it lexically blends into the rest of the text of code and can't be so easily identified).
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Muthuveerappan
I would appreciate any simple interpretation of reinterpret_cast and its use or any link that does that.
According to The C++ Standard Library by Josuttis, the behavior of reinterpret_cast is implementation defined. This means you need to consult the documentation of the actual compiler you're using to figure out what it does. This also means reinterpret_cast isn't portable.
Re: reinterpret_cast<> and where can it be used
So what everybody's said in this thread is allright because the C++ standard allows anything; Whatever you say is fine :)
The only sensible reaction is to never use reinterpret_cast, at least not if you're aiming for portability.