简体   繁体   English

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

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

I'm testing a small code fragment and I'm surprised the same representation of 4 bytes as put into std::array and std::tuple yield different in-memory layouts我正在测试一个小代码片段,我很惊讶 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";
}

For tuple the output is: 4278190080 , while for the array it is: 255 .对于元组,输出为: 4278190080 ,而对于数组,输出为: 255 Is this expected?这是预期的吗?

std::array has a layout specified by the standard, but std::tuple does not, and can be anything the implementation wants. std::array具有标准指定的布局,但std::tuple没有,并且可以是实现想要的任何东西。

So it's expected that they may differ, but of course they may also happen to choose the same layout, on some compilers/versions/platforms - there's just no guarantee.因此,预计它们可能会有所不同,但当然,它们也可能碰巧在某些编译器/版本/平台上选择了相同的布局 - 只是不能保证。

In practice one of the easiest ways to implement std::tuple is recursively, as it was originally done in the Loki library.实际上,实现std::tuple的最简单方法之一是递归,因为它最初是在 Loki 库中完成的。 This will lay the fields out in reverse order (the most-base class, whose subobject comes first, is the leaf for the last member of the typelist).这将以相反的顺序布置字段(最基类,其子对象首先出现,是类型列表最后一个成员的叶)。 That's not the only possible implementation though, and I have observed the field order differing between compilers/standard library implementations.但这并不是唯一可能的实现,我观察到编译器/标准库实现之间的字段顺序不同。


NB.注意。 as mentioned in a comment, your current diagnostic has UB - however, you can hexdump the 4 bytes at reinterpret_cast<char*>(&i.z) safely and get an equivalent result.如评论中所述,您当前的诊断具有 UB - 但是,您可以安全地在reinterpret_cast<char*>(&i.z)处对 4 个字节进行reinterpret_cast<char*>(&i.z)并获得等效结果。

std::array and std::tuple yield different in-memory layouts std::array 和 std::tuple 产生不同的内存布局

Is this expected?这是预期的吗?

Yes, this possibility is to be expected, although that isn't guaranteed.是的,这种可能性是可以预料的,尽管不能保证。

To be more specific, the memory order of array elements are such that lower indices are in lower memory addresses.更具体地说,数组元素的内存顺序是较低的索引位于较低的内存地址中。 The memory order of tuple elements is unspecified.元组元素的内存顺序未指定。 As a side-effect of the way that tuples are typically implemented, the inverse memory order is typical.作为元组通常实现方式的副作用,逆内存顺序是典型的。

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

This results in undefined behaviour.这会导致未定义的行为。 Tuples aren't (guaranteed to be) standard layout types, so you may not alias them as their first member.元组不是(保证是)标准布局类型,因此您不能将它们别名为它们的第一个成员。

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

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