Я не совсем уверен, действительно ли нужно иметь прототипы для статических функций в C. До тех пор, пока я не экспортирую такие функции (т.е. они не имеют внешней связи), какая другая польза может дать это
Спасибо.
Я не совсем уверен, действительно ли нужно иметь прототипы для статических функций в C. До тех пор, пока я не экспортирую такие функции (т.е. они не имеют внешней связи), какая другая польза может дать это
Спасибо.
например. если вам нужно убедиться, что функция имеет определенный тип, она может быть полезна.
Рассмотрим это:
// 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;
}
Чтобы привести некоторые полномочия, правило 8.1 MISRA-C: 2004 обеспечивает прототипы для функций с внешней связью, но также упоминает внутреннюю связь:
"Предоставление прототипа для функции с внутренней связью хорошая практика программирования".
Я считаю, что это хорошая практика, потому что это делает ваш стиль кодирования между функциями interal/external linkage последовательными. И, как говорили другие в своих ответах, это также удобно.
Если вы хотите использовать их перед реализацией, вы должны написать прототип.
Обычно вы можете изменить порядок функций, но что, если у вас есть две статические функции, которые называют друг друга?
Объявление без определения функции static
(это то же самое для функции extern
) позволяет вызывать функцию до того, как функция определена. В C идентификатор функции должен быть объявлен до того, как он может быть использован:
static void foo(void);
void bar(void)
{
foo();
}
static void foo(void)
{
...
}
Одно (незначительное) удобство заключается в том, что он позволит вам размещать функции в любом месте, где захотите. Например, если вы хотите разместить свои служебные функции в конце файла, вы должны объявить их.
Случай, когда вы должны объявить свои функции, - это когда у вас есть две взаимно рекурсивные функции, так как первая, помещенная в файл, еще не увидела другую функцию.
Если вы не укажете прототип функции, код, приведенный ниже, будет действительным.
static int bar()
{
};
int foo()
{
bar("asdf" );
};
И такие скрытые ошибки могут быть опасными. Проверка раздела "2 7.2.2 Проверка типа аргумента функции" снова может быть полезна Принципы и практика с использованием С++ [Bjarne Stroustrup].