Не удалось вывести границы из инициализатора для многомерных массивов

Этот следующий код не компилируется:

int main() {
int a[][] = { { 0, 1 },
{ 2, 3 } };
}

Сообщение об ошибке

error: declaration of 'a' as multidimensional array must have bounds for all dimensions except the first
int a[][] = { { 0, 1 },
^

Это указано стандартом? Если так, то почему? Я думаю, что определить границы здесь было бы очень легко.

1

Решение

Это указано стандартом?

Ну, да.

§8.3.4 / 3 Когда несколько «массивов» спецификаций являются смежными,
создан тип многомерного массива; только первая из констант
выражения, которые определяют границы массивов, могут быть опущены. В
дополнение к объявлениям, в которых используется неполный тип объекта
разрешено, граница массива может быть опущена в некоторых случаях в
объявление параметра функции (8.3.5). Связанный массив может также
быть опущено, когда за декларатором следует инициализатор (8.5).
В этом случае оценка рассчитывается из числа начальных
элементы (скажем, N) (8.5.1) и тип идентификатора
из D это «массив N T». Кроме того, если есть предшествующее
объявление объекта в той же области, в которой
указан, граница пропущенного массива принимается такой же, как в
более раннее объявление, и аналогично для определения статических данных
член класса.

Если так, то почему?

С одной стороны, массив не может быть построен из неполного типа (void например). Массив неизвестной границы является одним из тех неполных типов:

§8.3.4 / 1 … Объект типа массива содержит непрерывно распределенный
непустой набор N подобъекты типа T, За исключением случаев, указанных ниже, если
константное выражение опущено, тип идентификатора D
является » производный описатель типа-лист массив неизвестных границ T»,
неполный тип объекта. …

§8.3.4 / 2 Массив может быть построен из одного из основных типов
(Кроме void), из указателя, из указателя на член, из
класс из типа перечисления или из другого массива.

Более того:

§3.9 Класс, который был объявлен, но не определен, перечисление
введите в определенных контекстах (7.2), или массив неизвестного размера или
неполный тип элемента, является не полностью определенный объект
тип
.45

45) Размер и расположение экземпляра не полностью определенного
тип объекта неизвестен.

Я думаю, что определить границы здесь было бы очень легко.

Новички часто допускают ошибку, заключающуюся в том, что компилятор обладает магическими способностями. Компилятор работает с информацией это уже имеет, это не Создайте информация из воздуха. Если вы попросите его создать объект неизвестного размера, он просто не сможет это сделать. Смотрите следующие примеры:

Только самое внутреннее измерение может быть опущено. Размер элементов в
массив выводится для типа, заданного переменной массива.
Поэтому тип элементов должен иметь известный размер.

  • char a[] = { ... }; имеет элементы (например, a[0]) размера 1 (8 бит) и имеет неизвестный размер.
  • char a[6] = { ... }; имеет элементы размера 1 и имеет размер 6.
  • char a[][6] = { ... }; имеет элементы (например, a[0], который является массивом) размера 6, и имеет неизвестный размер.
  • char a[10][6] = { ... }; имеет элементы размера 6. и имеет размер 60.

Не положено:

  • char a[10][] = { ... }; будет иметь 10 элементов неизвестного размера.
  • char a[][] = { ... }; будет иметь неизвестное количество элементов неизвестного размера.

Источник

3

Другие решения

Других решений пока нет …