Есть ли способ иметь статические и общедоступные прототипы в одном заголовочном файле в C? - PullRequest
2 голосов
/ 27 октября 2011

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

Скажем, у меня есть заголовок 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();

Какая лучшая практика для этого, чем очевидное решение разделения файла заголовка на отдельный заголовок исключительно для статических прототипов и один для общедоступных?

Ответы [ 4 ]

4 голосов
/ 27 октября 2011

Вы не помещаете объявления статических функций в заголовочные файлы.Поскольку они являются локальными по отношению к файлу .c, который их определяет, нет смысла экспортировать их из файла заголовка.

Есть две вещи, которые вы можете сделать:

  1. Определите функцию до ее вызова в файле c (переместите определение a() над основным).
  2. Объявите статическую функцию вверху файла C (это мой личный выбор).В вашем случае вы перемещаете объявление a() в начало main.c.

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

3 голосов
/ 27 октября 2011

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

Вместо этого я бы предложил вам ставить только статические прототипыв файле .c вверху файла в том же файле они определены.

1 голос
/ 27 октября 2011

Если «статическая» функция, которую вы хотите определить, достаточно короткая или достаточно дешевая, вам лучше определить ее как static inline и поместить ее определение с ее телом (а не только с объявлением) в* .h заголовочный файл.

1 голос
/ 27 октября 2011

Если у вас есть объявление b() в main.h, зачем вам оно снова нужно в other.c, которое включает его? Кроме этого, все хорошо, не вижу никаких проблем.

Важно помнить о «нормальных» функциях, что все прямые объявления одной и той же функции (в данном случае b()) должны совпадать, иначе у вас будут проблемы (связывание ошибок, ошибки компилятора, что нет). В вашем случае они не совпадают.

Если, конечно, b(); не является фактическим вызовом функции, но, по крайней мере, в коде, который вы разместили, он выходит за пределы области видимости, поэтому рассматривается как прямое объявление.

Относительно static предварительных объявлений, они ограничивают видимость функции модулем компиляции. Таким образом, вызов a() в other.c не выполнит a(), реализованный в main.c. Вот и весь смысл static в C.

...