Почему я должен объявлять размер параметра массива C в заголовке функции?
Может кто-нибудь рассказать мне, почему я должен потрудиться указать размер аргумента массива C в заголовке функции? Например:
void foo (int iz[6]) { iz[42] = 43; }
С
int is[2] = {1,2,3};
получаем полезную ошибку. Возможно, это помогает с комментариями/документацией?
Ответы
Ответ 1
Может кто-нибудь рассказать мне, почему я должен потрудиться указать размер аргумента массива C в заголовке функции? Например:
void foo (const char sz [6]) {sz [42] = 43; }
ИМО, вы не должны. Когда вы пытаетесь передать массив функции, то, что действительно передается, является указателем на начало массива. Поскольку получаемая функция будет указателем, лучше написать ее, чтобы сделать это явным:
void foo(char const *sz)
Тогда, поскольку теперь ясно, что функции не было дано никакой информации о размере, добавьте это как отдельный параметр:
void foo(char const *sz, size_t size)
Ответ 2
Единственная значимая причина для этого - для целей документации - сообщить будущим пользователям, что функции ожидают получить массив по крайней мере, что многие элементы. Но даже это вопрос конвенции - что-то, что вы должны согласовать с другими пользователями заранее. Язык (компилятор) так или иначе игнорирует этот размер. Объявление вашей функции эквивалентно void foo(int iz[])
и void foo(int *iz)
.
Единственный способ сделать его несколько значимым для компилятора - объявить его как
void foo (int iz[static 6])
который обещает компилятору, что массив будет иметь по крайней мере 6 элементов, что означает, что компилятор сможет оптимизировать этот код с использованием этого предположения. Более того, если вы действительно хотите принять упомянутое выше соглашение, имеет смысл объявлять размеры массива с помощью static
конкретно, так как язык явно определяет семантику этой конструкции.
То, что вы подразумеваете под "мы получаем полезную ошибку", мне не ясно. Код
int is[2] = {1,2,3};
is[42] = 42;
не содержит нарушений ограничений. Он создает поведение undefined, но во время компиляции не требуется создавать диагностическое сообщение. Другими словами, нет, мы не получаем никакой "полезной ошибки" из этого.
Ответ 3
Это комментарий. Массивы понижаются до указателей в функциональных параметрах. Однако комментарии могут быть полезны, даже если компилятор их не читает.
Ответ 4
Это полезный комментарий, когда вы хотите сообщить клиентскому коду, что он должен передать массив определенного размера, i.e:
void foo(const char bar[5]);
/* It is expected that foo function receives an array of size 5 */
Однако документация не заменяет проверку кода:
void foo(const char bar[5])
{
if (!bar) error();
if (strlen(bar) != 4) error();
/* ... */
}