Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重新解释铸造<&燃气轮机;轻便性_C++_Casting_Reinterpret Cast - Fatal编程技术网

C++ 重新解释铸造<&燃气轮机;轻便性

C++ 重新解释铸造<&燃气轮机;轻便性,c++,casting,reinterpret-cast,C++,Casting,Reinterpret Cast,我读过一篇文章,如果使用不当,重新解释投射可能会很危险。所以我相信我使用它是正确的;)。我发现如果我有模板类和类型转换是必需的,那么使用它是很好的。但最近我读到,reinterpret\u cast也是不可移植的。我为这一点感到难过。原因是什么?以下面的代码为例 void Disp(int* val) { for (int i=0; i < SZ; ++i) { cout << *(val+i) << " "; } c

我读过一篇文章,如果使用不当,重新解释投射可能会很危险。所以我相信我使用它是正确的;)。我发现如果我有模板类和类型转换是必需的,那么使用它是很好的。但最近我读到,
reinterpret\u cast
也是不可移植的。我为这一点感到难过。原因是什么?以下面的代码为例

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;
}


我在Linux和Solaris中复制了同一程序的输出。我不熟悉可移植性问题。所以,谁能告诉我,如果我在代码中使用类似的东西,会不会导致移植性问题?即使没有使用此代码,当代码变得复杂(使用动态分配和所有配置)并长时间运行时,是否有可能出现意外(未定义的行为)。谢谢您的帮助。

此代码存在一些问题

  • 您正在显示未初始化数组的内容。这真的没有意义
  • 您正在硬编码循环的大小,假设
    sizeof(int)=4
    。如果您使用的机器大小不同
    int
    ,这将是不可移植的
  • 如果用除零以外的任何值填充内存,则需要担心处理器的端性

编辑:我看到您已编辑掉硬编码的魔法常数
4
,因此第2点不再适用。

我认为这是可以的。我看到有人认为它是未定义的,因为
[basic.lval]#10
中允许的别名列表不包括使用
int
对通过
char
类型写入的别名值进行定义。(但也包括与此相反的内容)

但是,我将“对象的存储值”解释为即使在通过
char
别名写入之后,仍然引用
int
值。这似乎并没有在C++标准中明确表达;但在C99中(这些规则显然是从C99派生出来的),它有不同的措辞,涉及有效类型,指定内存的有效类型仍然是
int
,尽管它是通过
char
别名写入的


澄清;在这两种语言中,还有其他规则涉及是否创建陷阱表示的问题。但是我已经看到,C++中的严格混叠规则胜过了这种情况下的规则。

< P>关于代码的可移植性/实用性的问题,RealTytCase将非常具体地说明它是如何使用的。无论在什么情况下,你可能会发现自己想要使用一个玩具的例子,得到答案都不会有帮助

一般来说,如果有一种方法可以不使用
reinterpret\u cast
来做某事,那么您应该这样做。使用问题中的示例,您可以通过使用
int*将数组清除为零,而无需使用
reinterpret\u cast
(尽管我认为您的示例中使用的
reinterpret_cast
实际上是定义良好且可移植的-使用已重新解释为
char*`的指针是少数可移植的领域之一)


在大多数情况下,您可能会发现您需要重新解释强制转换,您所处理的是一些确实不可移植的东西,您应该了解在特定情况下为什么需要重新解释强制转换,并了解特定情况下的可移植性问题。

reinterpret\u cast
在于,不同的CPU在内存中存储数字的方式不同。有些CPU将数字从最低有效字节存储到最高有效字节(小端),另一些CPU则恰恰相反(大端)。有些CPU甚至使用一些奇怪的字节顺序,如
1 0 3 2
,请不要问我为什么

无论如何,这样做的结果是,
reinterpret\u cast
是可移植的,只要您不以任何方式依赖字节顺序

您的示例代码不依赖字节顺序,它将所有字节视为相同的(将它们设置为零),因此代码是可移植的。如果您使用
reinterpret\u cast
在同一台机器上复制某些数据对象而不解释字节,那么代码也将是可移植的(
memcpy()
这样做)

不可移植的是查看第一个字节以确定数字的符号(仅适用于big-endian机器)。如果您试图通过仅发送重新解释\u cast的结果将数据从一台机器传输到另一台机器,您也会遇到麻烦:目标机器可能使用与源机器不同的字节顺序,从而完全错误地解释您的数据


我想说,“代码> RealTytRease是不可移植的,它只是将机器细节暴露给C++代码,它是机器特有的。任何依赖于该机器细节的代码都是不可移植的。

参见此:在指针类型之间的转换是可以的。我敢打赌,<代码> sieof(int)。在其中一台计算机中不是
4*sizeof(unsigned char)
。您应该使用
sizeof(int)
,而不是硬编码
4
。我已经更改了。谢谢。与其计算数组的大小,不如使用
I
。或者只使用
I<1[&arr]
。除了使用其他值初始化之外,我还需要担心其他问题吗?我的意思是,你能指出一些其他情况下,reinterpret_cast变得不可移植吗?@Sarath a对
char*
的强制转换是一种通用的,因此可以触发的问题有限。更大的问题是对象之间的强制转换根据编译器或设置的不同,可能会有不同的布局。或者换一种方式,即将
char*
转换为
int*
,在某些处理器上可能会遇到对齐问题。
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