根据type aliasing rules,我认为:
1)将uint64_t*
直接转换为uint32_t*
- 不正确(我无法通过结果ptr访问数据。请确保我将获得正确的数据值)
2)转换链确定(我可以安全地访问数据)
uint64_t* -> unsigned char* -> uint32_t*
uint64_t* -> void* -> uint32_t*
我是否正确理解规则?
我总是喜欢使用 union 来防止任何可能的ptr。转换问题(可能导致数据损坏),但并不总是可能(并且很好)解决方案。
答案 0 :(得分:1)
2)转换链是可以的(我可以安全地访问数据)
uint64_t* -> unsigned char* -> uint32_t* uint64_t* -> void* -> uint32_t*
我是否正确理解规则?
没有。像这样的链式reinterpret_cast
不会比直接reinterpret_cast
更正确。
我总是喜欢使用工会
使用union进行类型惩罚也会违反别名规则。
如果你有一个指向uint64_t
的指针,并且你想要使用对象中包含的八个字节中的四个(我假设一个8位字节)并将它们解释为uint32_t
,那么你必须首先决定你要使用的八个字节中的哪一个。毕竟,它们中的所有八个都不适合单uint32_t
。您想要低位字节还是高位字节?或者像其他字节一样更具异国情调?还要考虑,结果uint32_t
中的字节应该按顺序排列。
如果您希望根据其重要性使用特定字节,那么便携式方法是使用位移和掩码。
如果你想根据它们在内存中的位置来获取特定字节,那么便携式方法就是使用std::memcpy
。
答案 1 :(得分:-1)
如果你确定你的机器是大端或小端(几乎总是如此),你可以使用htonl()来检测字节序。在这两种体系结构中,uint64_t可以被视为uint32_t [2],它只是字节顺序不同。因此,您可以reinterpret_cast并根据字节顺序添加偏移量。虽然这是非标准的,但只有一种可能的大端和小端的实现(鸽子原理)。请注意,这不适用于例如中端架构(很少见但存在),或任何无法定义字节序的架构。