Как известно, в языке С ключевое слово static используется с глобальными переменными и функциями, чтобы ограничить их область видимости одним файлом. Для локальных переменных, static используется, чтобы переменная сохранялась в статически аллоцируемой памяти вместо автоматически аллоцируемой памяти. Хотя язык и не определяет реализацию каждого типа памяти, статически аллоцируемая память обычно резервируется в сегменте данных программы во время компиляции, а автоматически аллоцируемая память обычно реализуется в стеке. В С99 объявление вида void foo(double A[static 10]) означает, что эта A указывает на 10 валидных аргументов (от *A до A[9]). Эта нотация делает программу более информативной, помогает компилятору оптимизировать код функции foo, и проверить, что она вызывается корректно везде в программе.
Эта нотация была впервые введена в стандарте С99, и описывается в разделах 6.7.5.2 и 6.7.5.3:7. "Если ключевое слово static появляется в квадратных скобках [] в описании массива, значение соответствующего аргумента должно предоставлять доступ к массиву, содержащему как минимум столько элементов, сколько указано в выражении после static".
Пример программы:
#include void f(int p[static 1]) { printf("%d\n", *p); } int main() { int a = 0; f(&a + 1); f(0); f(&a); }
Clang делает предупреждение насчёт второго вызова, но, к сожалению, не для первого.
$ clang t.c
t.c:11:3: warning: null passed to a callee which requires a non-null argument
[-Wnonnull]
f(0);
^ ~
t.c:3:12: note: callee declares array parameter as static here
void f(int p[static 1])
^~~~~~~~~~~
1 warning generated.
Синтаксис может выглядеть немного странно, но комитет по стандартизации решил использовать уже существующее слово static, так как в данном случае оно не вызывает неоднозначностей и позволяет избежать введения нового ключевого слова (что могло бы поломать существующие программы).