Почему я должен объявлять размер параметра массива 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();
    /* ... */
}