繁体   English   中英

reinterpret_cast unsigned char * as uint64_t * - 这是UB吗?

[英]reinterpret_cast unsigned char* as uint64_t* - is this UB?

假设我们采用了unsigned char

std::array<uint8_t, 100500> blob;
// ... fill array ...

(注意:它已经对齐,问题不是关于对齐。)然后我们把它作为uint64_t[]并尝试访问它:

const auto ptr = reinterpret_cast<const uint64_t*>(blob.data());
std::cout << ptr[7] << std::endl;

转向uint64_t然后从中读取对我来说看起来很可疑。

但UBsan, -Wstrict-aliasing并没有触发它。 Google在FlatBuffers中使用此技术。 此外,Cap'n'Proto使用这个

是不确定的行为?

您无法通过其他类型的glvalue访问unsigned char对象值。 但相反的是授权,您可以通过unsigned char glvalue [basic.lval]访问任何对象的值:

如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:[...]

  • charunsigned charstd​::​byte类型。

因此,要符合100%标准,我们的想法是颠倒reinterpret_cast

uint64_t i;
std::memcpy(&i, blob.data() + 7*sizeof(uint64_t), sizeof(uint64_t));
std::cout << i << std::endl;

它将产生完全相同的组件

转换本身定义良好( reinterpret_cast永远不会有UB),但如果在该地址中没有构造uint64_t对象,则表达式“ ptr[7] ”中的左值转换的左值将是UB。

由于未显示“ // ... fill array ... ”,因此可能在该地址中构造了一个uint64_t对象(假设您所说的地址具有足够的对齐):

const uint64_t* p = new (blob.data() + 7 * sizeof(uint64_t)) uint64_t();

如果在该地址中构造了uint64_t对象,则所讨论的代码具有明确定义的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM