std::array 的地址是否保证与其数据相同?

Is the address of a std::array guaranteed the same as its data?

std::array 是...(引用自 cppreference):

This container is an aggregate type with the same semantics as a struct holding a C-style array T[N] as its only non-static data member.

这是否意味着数组的地址总是与其第一个元素的地址相同,即 data()

#include <array>
#include <iostream>

int main()
{
    std::array<int,6> x{};
    std::cout << &x << "\n";
    std::cout << x.data();
}

可能的输出:

0x7ffc86a62860
0x7ffc86a62860

如果是,这有什么用吗?是否允许以下​​内容?

int* p = reinterpret_cast<int*>(&x);
for (int i=0;i<6;++i){ std::cout << p[i]; }

从技术上讲,std::array 对象的开头可能有填充,在这种情况下,数据将位于比 std::array 对象更高的地址。只有 standard-layout 类 才能保证对象本身具有与第一个非静态数据成员相同的地址。

标准中不能保证 std::array<T, N> 是标准布局,即使 Tint 或类似的布局。 std::array<T, N> 的所有 合理 实现都将有一个 T[N] 类型的非静态数据成员,没有虚函数,并且最多只有一个没有虚函数的继承链base 类,这意味着只要 T 本身是标准布局,它们就会是标准布局。另外,即使 T 不是标准布局,编译器也不太可能在 std::array 对象的开头插入填充。

所以,虽然假设一个std::array<T, N>对象与其包含的第一个T对象具有相同的地址是不可移植的,但在实践中基本可以保证。您可以添加 static_assert(sizeof(std::array<T, N>) == sizeof(T[N])); 只是为了确保,如果有人试图在并非如此的奇异实现上构建您的代码,他们就会知道它不受支持。