Home > Back-end >  Is the address of a std::array guaranteed the same as its data?
Is the address of a std::array guaranteed the same as its data?

Time:10-09

std::array is ... (from 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.

Does that imply that the adress of an array is always the same as the adress of its first element, ie data() ?

#include <array>
#include <iostream>

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

Possible output:

0x7ffc86a62860
0x7ffc86a62860

And if yes, is this of any use? Is the following allowed?

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

CodePudding user response:

Technically, a std::array object may have padding at the beginning, in which case the data will be at a higher address than the std::array object. Only for standard-layout classes is there a guarantee that the object itself has the same address as the first non-static data member.

There is no guarantee in the standard that std::array<T, N> is standard-layout, even if T is int or something like that. All reasonable implementations of std::array<T, N> will have a single non-static data member of type T[N], no virtual functions, and at most a single inheritance chain with no virtual base classes, which would mean they would be standard-layout as long as T itself is standard-layout. Plus, even if T is not standard-layout, the compiler is not likely to insert padding at the beginning of the std::array object.

So, while an assumption that a std::array<T, N> object has the same address as the first T object it contains is not portable, it is basically guaranteed in practice. And you can add a static_assert(sizeof(std::array<T, N>) == sizeof(T[N])); just to be sure that, if someone ever tries to build your code on an exotic implementation where it isn't the case, they'll know it's not supported.

  • Related