В чем разница между объявлением функции и подписью? - PullRequest
36 голосов
/ 24 февраля 2010

В C или C ++, в чем разница между объявлением и сигнатурой функции?

Я знаю кое-что об объявлении функции, но сигнатура функции для меня совершенно новая. Какой смысл иметь концепцию сигнатуры функции? Для чего на самом деле используются две концепции?

Спасибо!

Ответы [ 5 ]

39 голосов
/ 24 февраля 2010

Объявление функции является прототипом для функции (или оно может быть получено из определения функции, если в этот момент компилятор не видел прототипа) - оно включает тип возвращаемого значения, имя функции и типы параметры (необязательно в C).

Подпись функции - это части объявления функции, которые компилятор использует для выполнения разрешения перегрузки. Поскольку несколько функций могут иметь одно и то же имя (т. Е. Они перегружены), компилятору нужен способ определить, к какой из нескольких возможных функций с определенным именем должен обращаться вызов функции. Подпись - это то, что компилятор считает в этом разрешении перегрузки. В частности, стандарт определяет «подпись» как:

информация о функции, которая участвует в разрешении перегрузки: типы ее параметров и, если функция является членом класса, cv-квалификаторы (если таковые имеются) для самой функции и класса, в котором функция-член объявлен.

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

6 голосов
/ 24 февраля 2010

Стандарт определяет два термина: объявление и определение. Определение является предварительным заявлением. Однако стандарты C99 и C ++ 03 имеют несколько разные определения.

Из C ++ 0x черновик:

Приложение C

8.3.5 Изменение: в C ++ объявлена ​​функция с пустым списком параметров не занимает аргументы. В C пустой параметр список означает, что количество и тип аргументы функции неизвестны "

Определения

1.3.11 подпись

имя и список параметров типа (8.3.5) функции, а также класс, концепция, концептуальная карта или пространство имен, членом которого оно является. Если функция или шаблон функции является член класса его подпись дополнительно включает в себя cv-квалификаторы (если есть) и ref-квалификатор (если есть) в функции или сам шаблон функции. подпись ограниченного члена (9.2) включает в себя свой шаблон требования. Подпись шаблон функции дополнительно включает в себя тип возвращаемого значения, его шаблон список параметров и его шаблон требования (если есть). Подпись специализации шаблона функции включает в себя подпись шаблона из которых это специализация и его аргументы шаблона (ли явно указано или выведено). [ Примечание: подписи используются в качестве основы для искажения имени и связывания. примечание]

3 голосов
/ 24 февраля 2010

Сигнатура функции не включает тип возврата или тип связи функции.

ОК, Википедия не согласен со мной по поводу типа возвращаемого значения. Однако я знаю, что возвращаемый тип не используется компилятором при принятии решения, соответствует ли вызов функции сигнатуре. Этот предыдущий вопрос StackOverflow, похоже, согласен: Является ли тип возвращаемого значения частью сигнатуры функции?

1 голос
/ 08 марта 2010

Также обратите внимание на то, что const верхнего уровня и volatile по аргументу не являются частью сигнатуры, согласно стандарту. Но некоторые компиляторы ошибаются.

, например

void f(const int, const char* const);

имеет такую ​​же подпись, как

void f(int, const char*);
0 голосов
/ 24 февраля 2010

Объявление функции является прототипом. Подпись функции указывает тип возвращаемого значения и используемые параметры, из которых состоит подпись. Учтите это:

int foo(int, int);  /* Function Declaration */


/* Implementation of foo 
** Function signature
*/
int foo(int a, int b){
}

Теперь рассмотрим такой сценарий: у программиста спрашивают, что такое сигнатура функции для foo:

  • Возвращает тип данных int
  • Два параметра также имеют тип данных int с именами a и b соответственно

Прототип функции, с другой стороны, должен указать компилятору C / C ++, что ожидать, и если сигнатура не совпадает с прототипом, компилятор выдаст ошибку в контексте объявления функции ошибка "или" несоответствие прототипа ".

...