reinterpret_cast<>和可移植性 [英] reinterpret_cast<> and portabilty

查看:185
本文介绍了reinterpret_cast<>和可移植性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读过,如果没有正确使用, reinterpret_cast<> 可能是危险的。所以我相信我使用它正确;)。我发现如果我有模板类和类型转换需要使用它是好的。但最近我看到 reinterpret_cast<> 是不可移植的。我很伤心的这一点。什么原因?获取以下代码

  void Disp(int * val)
{
for(int i = 0; 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;
}

现在输出:

  1174214872 32767 4196789 0 568392584 58 4196720 0 0 0 
0 0 0 0 0 0 0 0 0 0

机器类型: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

机器类型:SunOS DELPHI 5.10 Generic_142900-01 sun4u sparc SUNW,Netra-240



< ve复制了同一程序的输出,在Linux和Solaris中。我是新的可移植性问题。所以任何人都可以告诉我,如果我在我的代码中使用这样的东西,会导致任何可移植性问题?即使没有这个代码,是有机会的惊喜(​​未定义的行为),当代码变得复杂(动态分配和所有)和运行长时间。感谢您的帮助。

解决方案

reinterpret_cast<> 在于不同的CPU在存储器中以不同的方式存储数字。有些存储从最低有效字节到最高有效字节(小端),其他人正好相反(大端)。有些甚至使用一些奇怪的字节顺序像 1 0 3 2 ,不要问我为什么。



其结果是,只要你不以任何方式依赖字节顺序, reinterpret_cast<> p>

您的示例代码不依赖于字节顺序,它将所有字节视为相同(将其设置为零),以便代码可移植。如果您在不解释字节的情况下使用 reinterpret_cast<> 在同一台机器上复制一些数据对象,则代码也是可移植的 memcpy()这样做)。



不可移植的东西就像看第一个字节确定数字的符号(仅适用于大端机器)。如果你试图通过发送 reinterpret_cast< char *> 的结果将数据从一台机器传输到另一台机器,你也遇到了麻烦:目标机器可能使用不同的



我会说,这是错误的说, reinterpret_cast<> 是不可移植的,它只是将机器细节暴露给特定于机器的C ++代码。而依赖于该机器细节的任何代码是不可移植的。


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.

这篇关于reinterpret_cast&lt;&gt;和可移植性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆