Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the size of std::array defined by standard

In C++11 std::array is defined to have contiguous storage and performance that is no worse than an array, but I can't decide if the various requirements of the standard imply that std::array has the same size and memory layout as a normal array. That is can you count on sizeof(std::array<int,N>) == sizeof(int)*N or is that implementation specific?

In particular, is this guaranteed to work the way you would expect it to:

std::vector< std::array<int, N> > x(M); typedef (*ArrayPointer)[N]; ArrayPointer y = (ArrayPointer) &x[0][0]; // use y like normal multidimensional array 

It works in the two compilers I tried (GNU & Intel). Furthermore, all the 3rd party documentation I could find (like this), states that std::array is just as memory efficient as a plain array, which combined with the contiguous requirement would imply that it must have identical memory layout. However I can't find this requirement in the standard.

like image 639
pavon Avatar asked Sep 30 '13 20:09

pavon


People also ask

Is std :: array fixed size?

std::array is a container that encapsulates fixed size arrays. 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. Unlike a C-style array, it doesn't decay to T* automatically.

Is std :: array initialized?

std::array contains a built-in array, which can be initialized via an initializer list, which is what the inner set is.

Is std :: array heap allocated?

TL;DR: yes, it is on the stack. Those are implementation details, and there is at least one platform that does not use a traditional stack (but rather linked list of heap allocations for it).

Can the size of an array be declared at runtime in C++?

No. In an array declaration, the size must be known at compile time. You can�t specify a size that�s known only at runtime.


1 Answers

It's nearly required. Specifically, §23.3.2.1/2 says:

An array is an aggregate (8.5.1) that can be initialized with the syntax

array<T, N> a = { initializer-list }; 

where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.

Since it's an aggregate, it can't use any sort of constructor to convert the data in the initializer-list to the correct format. That really only leaves one possibility: about the only thing it can store are the values themselves.

I suppose it would be possible for an std::array to store some sort of auxiliary data following the specified data, such as extra memory set to some predefined value, so if you write past the end of the array, you'd probably change that data. The compiler/run-time would then check those values at shut-down, and if you'd changed the values, report your code's undefined behavior.

It's also possible that a compiler could do padding/alignment differently for an std::array than for a built-in array. One obvious example for which this could even be desirable would be to support super-alignment requirements, such as data for use with Intel's SSE instructions. A built-in array can't support super-alignment, but I think the specification of std::array might be barely loose enough to allow it.

Bottom line: without getting into questions of how many possibilities might exist, it's pretty clear that std::array doesn't necessarily have to follow the rule you're asking about.

like image 166
Jerry Coffin Avatar answered Sep 27 '22 23:09

Jerry Coffin