#c #static #header
#c #статический #заголовок
Вопрос:
Компилятор всегда будет скулить, когда я смешиваю общедоступные и статические прототипы в файле заголовка.
Допустим, у меня есть заголовок main.h со статическим прототипом для функции a и обычным прототипом для функции b. Затем я хочу #include
добавить заголовок в два файла .c, а именно main.c и other.c. В main.c мне нужно включить, поскольку я вызываю функцию перед любым прототипом.
main.h:
static int a(void);
int b(void);
main.c:
#include "main.h"
void main(){
a();
}
static int a(void){
/* do stuff */
}
int b(void){
/* do stuff */
}
other.c:
#include "main.h"
b();
Что лучше всего подходит для этого, чем очевидное решение разделения файла заголовка на отдельный заголовок исключительно для статических прототипов и один для общедоступных?
Комментарии:
1. Зачем вам вообще нужен прототип статической функции в заголовке? Кроме того,
void main()
? Если вы не работаете со встроенными системами, вам нужно кое-что объяснить…2. @Chris Я знаю, что это должно быть int. Просто хотел сделать код как можно меньше, чтобы я получил ответ 🙂
3. Я ценю усилия, направленные на то, чтобы не сбрасывать код, но никто не будет откладывать
return 0;
😉4. @Chris: Надеюсь, никто не будет отпугнут
int main()
ниreturn 0;
тем, ни другим, и это самый короткий из всех. Даже те, кто страдает от примитивного компилятора, должны хотя бы слышать о C99 😉
Ответ №1:
Вы не помещаете объявления статических функций в заголовочные файлы. Поскольку они являются локальными для .c
файла, который их определяет, нет смысла экспортировать их из файла заголовка.
Вы можете сделать две вещи:
- Определите функцию до ее вызова в файле c (переместите определение
a()
выше основного). - Объявите статическую функцию в верхней части файла C (это мой личный выбор). В вашем случае вы перемещаете объявление
a()
в началоmain.c
.
Если функция будет использоваться в нескольких единицах перевода, вы можете определить статическую функцию в файле заголовка. Это может быть полезно встроенным вместо статического, если у вас есть взрослый компилятор, поддерживающий C99.
Комментарии:
1. 3. определите статическую функцию в заголовочном файле. В этом примере
a
используется только в одном TU, поэтому, вероятно, его вообще не должно быть в заголовке (2 правильно). Но если вы действительно собираетесь использоватьa
в нескольких TU, это должно быть определено в заголовке, и это может быть полезноinline
вместоstatic
предположения, что у вас есть взрослый компилятор, поддерживающий C99.
Ответ №2:
Нет смысла иметь статические прототипы в заголовке, причина этого в том, что статические функции имеют область действия файла, поэтому ни один внешний модуль не может получить доступ к функциям.
Вместо этого я бы посоветовал вам размещать статические прототипы только в файле .c в верхней части файла в том же файле, в котором они определены.
Ответ №3:
Если у вас есть объявление b()
in main.h
, зачем оно вам снова нужно в other.c
том, что включает его? Кроме этого, все хорошо, не вижу никаких проблем.
Важный момент, который следует иметь в виду в отношении «обычных» функций, заключается в том, что все прямые объявления одной и той же функции ( b()
в данном случае) должны совпадать, иначе у вас возникнут проблемы (ошибки связывания, ошибки компилятора, чего нет). В вашем случае они не совпадают.
Если, конечно b();
, это не фактический вызов функции, но, по крайней мере, в коде, который вы опубликовали, он выходит за рамки любой области, поэтому рассматривается как прямое объявление.
Повторите static
прямые объявления, они ограничивают видимость функции единицей компиляции. Таким образом, вызов a()
in other.c
не приведет к выполнению a()
реализованного in main.c
. В этом весь смысл static
в C.
Ответ №4:
ЕСЛИ «статическая» функция, которую вы хотите определить, достаточно короткая или достаточно дешевая, вам лучше определить ее как статическую встроенную и поместить ее определение вместе с телом (а не только его объявление) в заголовочный файл * .h .