Ответ 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
не обязательно должен следовать правилу, о котором вы просите.