Является ли размер std:: array определенным стандартом

В С++ 11 std::array определено, что он имеет непрерывное хранилище и производительность, которая не хуже массива, но я не могу решить, подразумевают ли различные требования стандарта, что std:: array имеет одинаковый размер и макет памяти как обычный массив. То есть вы можете рассчитывать на sizeof(std::array<int,N>) == sizeof(int)*N или это конкретная реализация?

В частности, гарантируется ли это так, как вы ожидаете:

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

Он работает в двух компиляторах, которые я пробовал (GNU и Intel). Более того, все сторонние документы, которые я мог найти (как это), заявляют, что std:: array как память эффективен как простой массив, который в сочетании с смежным требование подразумевало бы, что он должен иметь идентичный макет памяти. Однако я не могу найти это требование в стандарте.

Ответ 1

Это почти необходимо. В частности, в §23.3.2.1/2 говорится:

Массив - это агрегат (8.5.1), который может быть инициализирован синтаксисом

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

где initializer-list - список, разделенный запятыми, до N элементов, типы которых могут быть конвертированы в T.

Поскольку он является агрегатом, он не может использовать какой-либо конструктор для преобразования данных в списке инициализаторов в правильный формат. Это действительно оставляет только одну возможность: единственное, что она может хранить, это сами ценности.

Я полагаю, что std::array может хранить какие-то вспомогательные данные, следующие за указанными данными, такие как дополнительная память, заданная для некоторого предопределенного значения, поэтому, если вы пишете прошлое конца массива, вероятно, измените эти данные. Затем компилятор/время выполнения проверяет эти значения при выключении, и если вы изменили значения, сообщите о своем коде undefined.

Также возможно, что компилятор может выполнять отступы/выравнивание по-разному для std::array, чем для встроенного массива. Одним из очевидных примеров, для которых это может быть даже желательно, будет поддержка требований суперуровневости, таких как данные для использования с инструкциями Intel SSE. Встроенный массив не может поддерживать супер-выравнивание, но я думаю, что спецификация std::array может быть достаточно свободной, чтобы позволить ему.

В нижней строке: не доходя до вопросов о том, сколько возможностей может существовать, довольно ясно, что std::array не обязательно должен следовать правилу, о котором вы просите.