首页 > 解决方案 > 内存顺序中的 std::array 和 std::tuple

问题描述

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

#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。这是预期的吗?

标签: c++c++17

解决方案


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

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

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


注意。正如评论中提到的,您当前的诊断有 UB - 但是,您可以reinterpret_cast<char*>(&i.z)安全地十六进制转储 4 个字节并获得等效结果。


推荐阅读