C 2018 6.9.1 обсуждает определения функций и говорит нам в параграфе 10:
При входе в функцию оцениваются выражения размера каждого изменяемого параметра…
В соответствии с 6.7.6 3, изменяемый тип - это тип, имеющий тип массива переменной длины в своих объявлениях, возможно, вложенный.(Таким образом, int a[n]
изменяемым образом изменяется, поскольку он является массивом переменной длины, а фиксированная длина int (*a[3])[n]
также изменяемым образом, поскольку вложенный в него тип массива переменной длины.)
Вв случае void foo(int n, int a[][n])
мы видим, что n
должен быть оценен, потому что компилятору нужен размер для вычисления адресов для выражений, таких как a[i][j]
.Однако для void foo(int n, int a[n])
такой необходимости не существует, и мне неясно, относится ли приведенный выше текст к типу параметра до корректировки (int a[n]
) или после корректировки (int *a
).
Насколько я помню, когда это впервые привлекло мое внимание несколько лет назад, я нашел и компилятор, который вычислял выражение, и компилятор, который этого не делал, для параметра прямого массива.Вызов foo
, который был определен с помощью void foo(int a[printf("Hello, world.\n")]) {}
, будет выводить или не выводить строку в зависимости от компилятора.В настоящее время при компиляции с Apple LLVM 10.0.0 и clang-1000.11.45.5 в macOS 10.14.2 выводится строка.(Как упомянуто выше, для типа вложенного массива, выражение должно быть оценено, и все компиляторы, которые я пробовал, показали это. К сожалению, в настоящее время я не помню, какие это были компиляторы.)
Не ясно, массивРазмер полезен для компилятора.Этот аспект стандарта C, возможно, не был полностью проработан.Есть функция, которая добавляет некоторое значение к размеру;если размер объявлен с static
:
void foo(int a[static SomeExpression]) { … }
, то в соответствии с 6.7.6.3 7, a
должно указывать как минимум SomeExpression
элементов.Это означает, что a
не должно быть нулевым, что компилятор может использовать для оптимизации некоторых вещей.Однако у меня нет примеров того, как само число может помочь с оптимизацией или другими аспектами компиляции.