Этот следующий код не компилируется:
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 },
^
Это указано стандартом? Если так, то почему? Я думаю, что определить границы здесь было бы очень легко.
Это указано стандартом?
Ну, да.
§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[][] = { ... };
будет иметь неизвестное количество элементов неизвестного размера.
Других решений пока нет …