C++ 重新解释转换链的正确性

C++ 重新解释转换链的正确性,c++,types,casting,type-conversion,reinterpret-cast,C++,Types,Casting,Type Conversion,Reinterpret Cast,根据报告,我假设: 1) 将uint64\u t*直接转换为uint32\u t*-不正确(我无法通过结果ptr访问数据。请确保我将获得正确的值) 2) 转换链正常(我可以安全访问数据) 我是否正确理解规则 我总是更喜欢使用工会,以防止任何可能的ptr。转换问题(可能导致数据损坏),但这并非总是可能的(也是好的)解决方案 2) 转换链正常(我可以安全访问数据) 我是否正确理解规则 不可以。像这样的链式的reinterpret\u cast不会比直接的reinterpret\u cast更正确 我

根据报告,我假设:

1) 将
uint64\u t*
直接转换为
uint32\u t*
-不正确(我无法通过结果ptr访问数据。请确保我将获得正确的值)

2) 转换链正常(我可以安全访问数据)

我是否正确理解规则

我总是更喜欢使用工会,以防止任何可能的ptr。转换问题(可能导致数据损坏),但这并非总是可能的(也是好的)解决方案

2) 转换链正常(我可以安全访问数据)

我是否正确理解规则

不可以。像这样的链式的
reinterpret\u cast
不会比直接的
reinterpret\u cast
更正确

我总是喜欢用工会来代替

使用联合进行类型双关也违反了别名规则


如果您有一个指向
uint64_t
的指针,并且希望使用对象中包含的八个字节中的四个(我假设是一个8位字节),并将它们解释为
uint32_t
,那么您必须首先决定要使用八个字节中的哪一个。毕竟,它们八个都不能放在一个
uint32\u t
中。您想要低阶字节还是高阶字节?或者是更奇特的东西,比如每一个字节?还要考虑,字节应该在结果的<代码> UTI32 32 t < /代码>中。

如果需要基于重要性的特定字节,那么可移植的方法是使用位移位和掩码

如果您需要基于其在内存中的位置的特定字节,那么可移植的方法是使用
std::memcpy

2) 转换链正常(我可以安全访问数据)

我是否正确理解规则

不可以。像这样的链式的
reinterpret\u cast
不会比直接的
reinterpret\u cast
更正确

我总是喜欢用工会来代替

使用联合进行类型双关也违反了别名规则


如果您有一个指向
uint64_t
的指针,并且希望使用对象中包含的八个字节中的四个(我假设是一个8位字节),并将它们解释为
uint32_t
,那么您必须首先决定要使用八个字节中的哪一个。毕竟,它们八个都不能放在一个
uint32\u t
中。您想要低阶字节还是高阶字节?或者是更奇特的东西,比如每一个字节?还要考虑,字节应该在结果的<代码> UTI32 32 t < /代码>中。

如果需要基于重要性的特定字节,那么可移植的方法是使用位移位和掩码



如果您需要基于其在内存中的位置的特定字节,那么可移植的方法是使用
std::memcpy

如果您确定您的机器是大的或小的endian(几乎总是这样),您可以使用htonl()来检测endianness。在这两种体系结构上,uint64_t可以看作uint32_t[2],只是字节顺序不同。因此,您可以重新解释_cast并基于端点度添加偏移。虽然这是非标准的,但只有一种可能的实现方式,即big-endian和little-endian(鸽子洞原理)。请注意,这不适用于例如中间端结构(虽然很少见但存在),或任何无法定义端结构的结构。

如果您确定您的机器是大端或小端结构(几乎总是这样),您可以使用htonl()来检测端结构。在这两种体系结构上,uint64_t可以看作uint32_t[2],只是字节顺序不同。因此,您可以重新解释_cast并基于端点度添加偏移。虽然这是非标准的,但只有一种可能的实现方式,即big-endian和little-endian(鸽子洞原理)。请注意,这不适用于例如中间端结构(虽然很少见,但存在),或任何无法定义端结构的结构。

否,将字符指针重新解释为指向不是实际类型的类型的指针是UB,因此链不起作用。还可以使用并集来实现相同的结果是UB。这很奇怪,cppreference的部分只讨论多态对象。如果可能的话,您可能应该尝试截断指向的值,而不是摆弄指针本身。不,将char指针重新解释为指向非实际类型的类型的指针是UB,因此,您的链不起作用。同时使用union来实现相同的结果是UB。奇怪的是,cppreference的部分只讨论多态对象。如果可能的话,您可能应该尝试截断指向的值,而不是玩弄指针本身。“读取正确字节的便携式方法是使用位移位和掩码“-在我看来,0xFF掩码将为我带来最低有效字节,它位于最低地址st。在little endian机器中,而在big endian机器中则相反,因此相同的掩码将针对不同字节的内存。如果我错了,请纠正我。另一种方法是
memcopy
将您想要的字节放入接收变量。@amabocarb正确。掩码为您提供低阶字节,而不考虑endianness。@Justin Time,无论使用哪个endiannes,LSB掩码都将始终为0xFF。你的屏蔽仍然正确,但是为了另一个目的:访问“最高地址字节”:)@AmaboCarab哦,我的错。感谢您指出这一点,我发现endian ness有时有点令人困惑。“读取正确字节的可移植方法是使用位移位和掩码”-在我看来,0xFF掩码将为我带来最低有效字节,位于最低地址。在little endian机器中,而在big endian机器中则相反,因此相同的掩码将针对不同字节的内存。如果我错了,请纠正我。替代方法是
memcopyuint64_t* -> unsigned char* -> uint32_t*

uint64_t* -> void* -> uint32_t*
uint64_t* -> unsigned char* -> uint32_t*

uint64_t* -> void* -> uint32_t*