What is sizeof std :: array <char, N>?

What does the C ++ standard say about what sizeof(std::array<char, N>) (for some constant N )?

In a comment on another question, it was mentioned that std::array does not always stack out. The comment was in response to another comment that suggested that adding too many constants for std::array declared as a local variable could cause the program to be interrupted due to insufficient resources for the variable "stacked". I assume that the following comment meant that std::array would be possible to somehow switch to dynamic allocation mode.

I could imagine that there could be some kind of SFINAE that could be applied to an array size threshold that starts the std::array specialization, which actually distributes and manages the array dynamically. In this case, sizeof(std::array<...>) may just be a pointer. It is allowed?

+4
source share
1 answer

Obviously sizeof(std::array<char, N>) != N if N == 0 . This is also not necessarily true for N > 0 . Β§23.3.2.1 [array.overview] / p1-2:

The <array> header defines a class template for storing a fixed size of a sequence of objects. The array supports random access iterators. an array<T, N> instance stores N elements of type T , so size() == N is an invariant. The elements of the array are stored adjacent, which means that if a is array<T, N> , then it obeys the identity &a[n] == &a[0] + n for all 0 <= n < N .

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

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

where initializer-list is a comma-separated list of up to N elements whose types can be converted to T

Β§8.5.1 [dcl.init.aggr] / p1:

An aggregate is an array or class (section 9) without any custom constructors (12.1), private or protected non-static data elements (Section 11), there are no base classes (section 10), and there are no virtual functions (10.3).

Since array is an aggregated type, it cannot have a custom constructor that performs dynamic allocation, and it must store the elements directly, since it must be able to initialize from the list of initializers using aggregate initialization. However, nothing in the standard allows an implementation to add extra materials after a member of a C-style array<T, N> a = { initializer-list }; if array<T, N> a = { initializer-list }; has certain semantics when the list of initializers contains no more than N members. Implementation that looks like

 template<typename T, size_t N> struct array { //typedefs and member functions omitted T _Elems[N]; double _Because_I_can; }; // specialization for N == 0 case omitted 

is completely legal. Therefore, there is no guarantee that sizeof(std::array<char, N>) == N

+9
source

Source: https://habr.com/ru/post/1272163/


All Articles