Click to See Complete Forum and Search --> : reinterpret_cast question
axr0284
July 14th, 2006, 01:28 PM
Hi,
I have been reading in a lot of places that using reinterpret_cast is bad but they never explain the reason for it. I use it a lot in my code to convert int to char * since I need to send the individual bytes of the int across a network.
<CODE>
char *byteCrcPtr = NULL;
DWORD byteCrc = 0xFF23F2e4;
byteCrcPtr = reinterpret_cast<char *>(&byteCrc);
for(int i=0;i<sizeof(DWORD);i++) {
packet[i]= byteCrcPtr[i];
}
</CODE>
To convert back
<CODE>
DWORD byteCrc = *(reinterpret_cast<DWORD*>(&packet[9]));
</CODE>
I especially want to understand why this is bad and is there a better way to do this. Thanks
Amish
exterminator
July 14th, 2006, 02:19 PM
Recall how guns can be useful and can be mis-used as well ;). The language features that are misused most of the times are sometimes suggested as dangerous to use .. but sometimes their need is reasonable and that explains their presence.
The basic idea is type-safety. reinterpret cast (i will call it RC henceforth) is capable of casting any type to any other type and back successfully. Whenever, you are designing an application you would not want to play with types in that sense, else one single variant type should have had been sufficient in any programming language, though I cannot bet.
C++ is a strongly typed language. And one's design should respect that otherwise it will lead to a messed up application with hard-to-spot-errors. This has been proven time and again. You lose the type information and for some other casting operators, you get an overhead.
dude_1967
July 14th, 2006, 02:21 PM
reinterpret_cast is used to cast unrelated types such as a pointer to an integer. I believe that the use of reinterpret_cast is not guaranteed to be portable. Furthermore, using reinterpret_cast is very heavy-handed and might mask problematic design issues.
Many developers use a combination of two static_cast's to cast pointer to integral types.
Sincerely, Chris.
axr0284
July 14th, 2006, 05:05 PM
Thanks for the reply. Exterminator could you explain more about what you mean by "You lose the type information and for some other casting operators, you get an overhead."
Also any idea how to cast an integer into a char pointer. The problem is that I need to create a packet containing the individual bytes that make up the integer. It is to be used as a packet in a network application.
I'll also look into static cast. Thanks
Amish
SuperKoko
July 14th, 2006, 05:31 PM
I have been reading in a lot of places that using reinterpret_cast is bad but they never explain the reason for it. I use it a lot in my code to convert int to char * since I need to send the individual bytes of the int across a network.
reinterpret_cast is very non-portable and leads easily to undefined behavior.
During a long time I even thought that you couldn't reinterpret_cast a pointer to another pointer to char and use this pointer to char, though, now that I have read [expr.reinterpret_cast]-10 in the ISO 14882:1998 standard, I think that it can be portable.
Anyway, reinterpret_cast is very dangerous : You must keep constantly in mind things like data alignment and the original type of the pointer.
http://www.codeguru.com/forum/showpost.php?p=1385744
Furthermore, even if this use of reinterpret_cast<char*> is defined by the ISO standard, the resulting char have unspecified values.
As example, your code:
I have been reading in a lot of places that using reinterpret_cast is bad but they never explain the reason for it. I use it a lot in my code to convert int to char * since I need to send the individual bytes of the int across a network.
<CODE>
char *byteCrcPtr = NULL;
DWORD byteCrc = 0xFF23F2e4;
byteCrcPtr = reinterpret_cast<char *>(&byteCrc);
for(int i=0;i<sizeof(DWORD);i++) {
packet[i]= byteCrcPtr[i];
}
</CODE>
To convert back
<CODE>
DWORD byteCrc = *(reinterpret_cast<DWORD*>(&packet[9]));
</CODE>
Will only work on an homegenous network (i.e. all machines must share the same byte order).
If you want to avoid this problem, you should use htonl and ntohl
DWORD byteCrc = 0xFF23F2e4; // assume that DWORD is available on all the machines of the network.
DWORD nByteCrc=htonl(byteCrc); // required for using the network (host neutral) byte order.
memcpy(packet, &nByteCrc, sizeof(DWORD)); // a good old memcpy is fine here, std::copy too.
The basic idea is type-safety. reinterpret cast (i will call it RC henceforth) is capable of casting any type to any other type and back successfully.
Not always *successfully*!
reinterpret_cast is more dangerous than that!
The intermediate, mediator, type must have a less strict alignment requirement than the original type.
i.e., on 68000 or PowerPC processors, this code:
const char* p="hello";
const char* q=reinterpret_cast<const char*>(reinterpret_cast<const int*>(p));
char x=*q; // Undefined behavior : Actually, implementation-specific documentation might give the behavior of this line, but it is not portable!
kuphryn
July 14th, 2006, 06:24 PM
reinterpret_cast arbitrary types similar operator [] random access must be careful
Kuphryn
exterminator
July 15th, 2006, 02:19 AM
The intermediate, mediator, type must have a less strict alignment requirement than the original type.I must agree with this. Here's a good read tht I found : reinterpret_cast (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndeepc/html/deep06012000.asp)
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.