繁体   English   中英

内存顺序中的 std::array 和 std::tuple

[英]std::array and std::tuple in memory order

我正在测试一个小代码片段,我很惊讶 4 个字节的相同表示与放入 std::array 和 std::tuple 产生不同的内存布局

#include <iostream>
#include <tuple>
#include <array>

struct XYZW {
  uint32_t x;
  uint32_t y;
  //std::array<uint8_t,4> z;
  std::tuple<uint8_t, uint8_t, uint8_t, uint8_t> z;
  uint32_t w;
};


int main() {
  XYZW i;
  i.z = {255, 0, 0, 0};
  uint32_t z = (*reinterpret_cast<uint32_t*>(&i.z));
  std::cout << z << " \n";
}

对于元组,输出为: 4278190080 ,而对于数组,输出为: 255 这是预期的吗?

std::array具有标准指定的布局,但std::tuple没有,并且可以是实现想要的任何东西。

因此,预计它们可能会有所不同,但当然,它们也可能碰巧在某些编译器/版本/平台上选择了相同的布局 - 只是不能保证。

实际上,实现std::tuple的最简单方法之一是递归,因为它最初是在 Loki 库中完成的。 这将以相反的顺序布置字段(最基类,其子对象首先出现,是类型列表最后一个成员的叶)。 但这并不是唯一可能的实现,我观察到编译器/标准库实现之间的字段顺序不同。


注意。 如评论中所述,您当前的诊断具有 UB - 但是,您可以安全地在reinterpret_cast<char*>(&i.z)处对 4 个字节进行reinterpret_cast<char*>(&i.z)并获得等效结果。

std::array 和 std::tuple 产生不同的内存布局

这是预期的吗?

是的,这种可能性是可以预料的,尽管不能保证。

更具体地说,数组元素的内存顺序是较低的索引位于较低的内存地址中。 元组元素的内存顺序未指定。 作为元组通常实现方式的副作用,逆内存顺序是典型的。

 uint32_t z = (*reinterpret_cast<uint32_t*>(&i.z));

这会导致未定义的行为。 元组不是(保证是)标准布局类型,因此您不能将它们别名为它们的第一个成员。

暂无
暂无

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

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