Терминология: форвардная декларация против прототипа функции
Для меня эти термины по сути являются синонимами при использовании языка программирования C. На практике я мог бы предпочесть "форвардную декларацию" для прототипов внутри файла в сравнении с "прототипом функции" для прототипов, включенных через файл заголовка. Но даже это искусственное различие, когда вы рассматриваете, что происходит после предварительной обработки. Возможно, я что-то упустил.
Существует ли консенсус в отношении того, когда использовать один термин в сравнении с другим?
Ответы
Ответ 1
ИМО это не синонимы.
Для меня "прототип функции" относится к имени функции и ее параметрам и типам возврата. Это относится не только к тому, что вы называете "форвардной декларацией". Все функции имеют прототип.
Мы чаще делаем разницу между функцией declare и ее соответствующим определением.
Ответ 2
Термин "prototype" относится к конкретному синтаксису объявления; в частности, что количество и типы параметров функции появляются в декларации. Для определения функции
int foo(int a, char *b) {...}
у вас может быть любое из следующих объявлений:
int foo(); // a declaration, but not a prototype
int foo(a, b); // a declaration, but not a prototype
int foo(int, char *); // a declaration and a prototype
int foo(int a, char *b); // a declaration and a prototype
Ответ 3
Я использую выражение term forward для следующего вида объявления struct
с определением.
struct Foo;
Объявление функции не обязательно должно быть полным прототипом, совместимым с pre-1989 (K & R) C.
char *foo(); // NOT the same as char *foo(void)
Ответ 4
Единственная концепция в C, о которой я знаю, - это различие между декларацией и определением. Прототип - это объявление и может происходить где угодно, в любое время и в определении, которое является фактической реализацией данного объекта. по этой концепции нет вещи, называемой форвардной декларацией, а только порядком декларации.
Ответ 5
Я не знаю, есть ли консенсус, но я думаю, что самый чистый способ сделать это:
- Поместите все объявления в заголовочные файлы, а не в исходные или .c файлы. (Я думаю, что вы имеете в виду объявление, когда вы произносите декларацию.)
- Поместите все определения в исходные файлы
Мне не нравится размещать объявления в файлах, потому что вы можете иметь конфликтующие объявления без ошибок в C, что может вызвать segfaults, например: if a.c имеет
int foo(char *str_one, char *str_two, char *str_three);
и b.c имеет
int foo(char *str_one, char *str_two);
вы не получите предупреждений или ошибок, а вызовы, сделанные foo() из bc, не будут размещать все параметры в стеке, где они должны быть, то есть foo() просто возьмет что-то из стека и обработает его как str_three, возможно, приводя к segfault. Поэтому для меня декларации переходят к файлам заголовков и определениям в исходные файлы.