Прототипы для "статических" функций

Я не совсем уверен, действительно ли нужно иметь прототипы для статических функций в C. До тех пор, пока я не экспортирую такие функции (т.е. они не имеют внешней связи), какая другая польза может дать это

Спасибо.

Ответ 1

например. если вам нужно убедиться, что функция имеет определенный тип, она может быть полезна.

Рассмотрим это:

// Define how the functions should be defined.
typedef void * jobfunc(void *);

// Use case
void addjob(jobfunc *);

// Ensure they have the right type. Without this, you only get a warning
// for addjob(job2) (see below) - with it, you get an error for the mismatch.
static jobfunc job1;
static jobfunc job2;

// Define one job
static void * job1(void * arg) {
    return NULL;
}

// Define another job - accidentally wrong.
static void * job2(int accidentally_wrong) {
    return NULL;
}

Ответ 2

Чтобы привести некоторые полномочия, правило 8.1 MISRA-C: 2004 обеспечивает прототипы для функций с внешней связью, но также упоминает внутреннюю связь:

"Предоставление прототипа для функции с внутренней связью хорошая практика программирования".

Я считаю, что это хорошая практика, потому что это делает ваш стиль кодирования между функциями interal/external linkage последовательными. И, как говорили другие в своих ответах, это также удобно.

Ответ 3

Если вы хотите использовать их перед реализацией, вы должны написать прототип.

Обычно вы можете изменить порядок функций, но что, если у вас есть две статические функции, которые называют друг друга?

Ответ 4

Объявление без определения функции static (это то же самое для функции extern) позволяет вызывать функцию до того, как функция определена. В C идентификатор функции должен быть объявлен до того, как он может быть использован:

static void foo(void);

void bar(void)
{
    foo();
}

static void foo(void)
{
    ...
}

Ответ 5

Одно (незначительное) удобство заключается в том, что он позволит вам размещать функции в любом месте, где захотите. Например, если вы хотите разместить свои служебные функции в конце файла, вы должны объявить их.

Случай, когда вы должны объявить свои функции, - это когда у вас есть две взаимно рекурсивные функции, так как первая, помещенная в файл, еще не увидела другую функцию.

Ответ 6

Если вы не укажете прототип функции, код, приведенный ниже, будет действительным.

static int bar()
{

};

int foo()
{
   bar("asdf" );
};

И такие скрытые ошибки могут быть опасными. Проверка раздела "2 7.2.2 Проверка типа аргумента функции" снова может быть полезна Принципы и практика с использованием С++ [Bjarne Stroustrup].