I've read that reinterpret_cast<>
can be dangerous if not used properly. So I believe that i was using it properly ;). I found it's good to use if I've templates classes and type conversion is required on that. But recently I've read that reinterpret_cast<>
is non-portable too. I'm sad for this point. What's the reason? Take the following code,
void Disp(int* val)
{
for (int i=0; i < SZ; ++i)
{
cout << *(val+i) << " ";
}
cout << endl;
}
int main()
{
int arr[SZ];
Disp(arr);
unsigned char* ptr = reinterpret_cast<unsigned char*>(arr);
for (unsigned char* i = ptr; i < (ptr + (SZ * sizeof(int))); i++)
{
*i = 0;
}
Disp(arr);
return 0;
}
Now the outputs:
1174214872 32767 4196789 0 568392584 58 4196720 0 0 0
0 0 0 0 0 0 0 0 0 0
Machine type: Linux 2.6.32-358.11.1.el6.x86_64 #1 x86_64 x86_64 x86_64 GNU/Linux
975580 -16506540 -13369152 0 -4202936 67876 3 -4202836 4 -4202828
0 0 0 0 0 0 0 0 0 0
Machine type: SunOS DELPHI 5.10 Generic_142900-01 sun4u sparc SUNW,Netra-240
I've copied the outputs of the same program, both in Linux and Solaris. I'm new to portability issues. So can anyone please tell me, if I'm using something like this in my code, will that cause any portability issues? Even if not with this code, is there a chance for surprises (undefined behavior) when the code get complex (with dynamic allocation and all) and running for long hours. Thanks for the help.
The portability issue with reinterpret_cast<>
lies in the fact that different CPUs store numbers differently in memory. Some store them from the least significant byte up to the most significant one (little endian), others do it precisely the other way around (big endian). Some even use some weird byte order like 1 0 3 2
, don't ask me why.
Anyway, the consequence of this is, that reinterpret_cast<>
is portable as long as you do not rely on the byte order in any way.
Your example code does not rely on byte order, it treats all bytes the same (setting them to zero), so that code is portable. If you would use a reinterpret_cast<>
to copy some data object on the same machine without interpreting the bytes, the code would also be portable (memcpy()
does this).
What is not portable is stuff like taking a look at the first byte to determine the sign of a number (works only on big endian machines). If you try to transfer data from one machine to another by just sending the result of reinterpret_cast<char*>
, you are also in trouble: the target machine may use a different byte order than the source machine, completely misinterpreting your data.
I would say that it is wrong to say that the reinterpret_cast<>
is non-portable, it simply exposes a machine detail to the C++ code which is machine-specific. And any code that relies on that machine detail is non-portable.
There are some problems with this code.
sizeof(int) == 4
. If you are on a machine with a different size int
, this will be non-portable.Edit: I see you've edited out the hard-coded magic constant 4
so point 2 no longer applies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With