Подтвердить что ты не робот

Терминология: форвардная декларация против прототипа функции

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

Существует ли консенсус в отношении того, когда использовать один термин в сравнении с другим?

4b9b3361

Ответ 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. Поэтому для меня декларации переходят к файлам заголовков и определениям в исходные файлы.