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

vla*_*don 6 c++ undefined-behavior

假设我们采用了一大堆unsigned chars.

std::array<uint8_t, 100500> blob;
// ... fill array ...
Run Code Online (Sandbox Code Playgroud)

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

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

uint64_t对我来说,施放然后阅读它看起来很可疑.

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

是不确定的行为?

Oli*_*liv 6

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

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

  • 一个char,unsigned 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;
Run Code Online (Sandbox Code Playgroud)

它将产生完全相同的组件.