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