Внимательное прочтение стандарта проясняет, что в C99 и C11 декларация считается нарушением ограничения. C11 6.7.2.6 Объявления массива p1
- В дополнение к необязательным квалификаторам типов и ключевому слову static,
[
и ]
могут разделять выражение или *
.Если они разграничивают выражение (которое определяет размер массива), выражение должно иметь целочисленный тип.Если выражение является константным выражением, оно должно иметь значение больше нуля. Тип элемента не должен быть неполным или типом функции .Необязательные квалификаторы типов и ключевое слово static должны появляться только в объявлении параметра функции с типом массива, а затем только при выводе самого внешнего типа массива.
Поскольку он содержит ссылки на *
, который действителен только в объявлениях функций, которые не являются определениями , и нигде больше, ограничения в целом должны бытьпринимается как применение к параметрам.
Для C90 дело обстоит сложнее.Это на самом деле обсуждается в C90 Отчете о дефектах 47 от 10 декабря 1992 г. .
2 из 6 приведенных объявлений:
/* 1. */ struct S;
/* 3. */ struct S *g(struct S a[]) { return a; }
и отчет о дефекте спрашивает, строго ли они соответствуют.Следует отметить, что в отличие от вопроса, это прототипы, которые являются частью определения , а не просто декларацией.
Тем не менее, стандартный комитет отвечает, что
* struct S
- неполный тип (подпункт 6.5.2.3, стр. 62, строки 25-28).Кроме того, массив неизвестного размера является неполным типом (подраздел 6.5.4.2, стр. 67, строки 9-10). Таким образом, массивы любого из вышеперечисленного строго не соответствуют (подпункт 6.1.2.5, стр. 23, строки 23-24).Это делает декларации 3 , 4 и 6 не совсем соответствующими.(Но реализация могла бы сделать это правильно.)
Кроме того, параметры массива настраиваются в соответствии с типом указателя (подраздел 6.7.1, стр. 82, строки 23-24). Однако нет ничего, что предполагало бы, что не строго соответствующий тип массива может волшебным образом быть преобразован в строго соответствующий параметр указателя с помощью этого правила.
Указанные типы могут интерпретироваться двумяразличные пути.(Преобразование массива в указатель может произойти как можно скорее или как можно позже.) Следовательно, программа, использующая такую форму, имеет неопределенное поведение.
(выделениемой)
Поскольку это не разъяснялось в письменной форме с 1992 , мы должны согласиться с тем, что поведение не определено, и поэтому стандарт C не предъявляет никаких требований и компилятор, который успешно скомпилирует это, он все еще может соответствовать C90.
Комитет также заявляет, что в C90 нет нарушения ограничений , поэтому компилятору, соответствующему C90, не нужно выводить какие-либо диагностические данные.
Я отредактировал ответ;Ранее я утверждал, что это будет относиться к C99 и C11 одинаково, но текст был изменен в C99, как указано выше, поэтому это нарушение ограничения в C99, C11.