в чем разница между объявлением функции и подписью?

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

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

Спасибо!


person Tim    schedule 24.02.2010    source источник
comment
Формально в C нет такой вещи, как сигнатура функции. В C просто нет необходимости в концепции сигнатуры функции. Ваш вопрос чисто С++. Это совершенно бессмысленно в C.   -  person AnT    schedule 08.03.2010
comment
Тогда, конечно же, осмысленный ответ на языке C — ни один, нет?   -  person John McFarlane    schedule 12.06.2021


Ответы (5)


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

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

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

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

person Michael Burr    schedule 24.02.2010
comment
Не совсем правильно говорить, что объявление функции является прототипом. В C++ это практически правильно, но терминологически неправильно, так как в C++ нет такого термина, как прототип. В C это строго неверно, потому что в C объявление функции не обязательно является прототипом. Например, void foo(); — это объявление функции, которое не вводит прототип в C. На самом деле этот вопрос не должен быть помечен как C, поскольку в C нет понятия сигнатуры функции. Это чисто вопрос C++, и по этой причине , в ответе не должно упоминаться никаких прототипов. - person AnT; 08.03.2010
comment
Не могли бы вы указать источники? - person Manuel Arwed Schmidt; 03.11.2015
comment
Вы ввели подпись, объявление, прототип и определение без четких различий. Не могли бы вы отредактировать это, чтобы добавить конкретный пример каждого? - person Andy Ray; 01.07.2021

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

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

Приложение C

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

Определения

1.3.11 подпись

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

person dirkgently    schedule 24.02.2010
comment
Спасибо, но мне трудно понять, что вы пытаетесь сказать. - person Tim; 24.02.2010
comment
Я знаю объявление функции, но сигнатура функции для меня совершенно новая. Какой смысл иметь понятие сигнатуры функции? Для чего на самом деле используются эти два понятия? - person Tim; 24.02.2010
comment
@Tim: 1) Стандарт C не определяет термин подпись. Он широко используется в общей литературе по программированию и часто является синонимом объявления функции. Обратите внимание, что объявления функций не обязательно должны иметь параметры. Определения, однако, если вы используете их в определении. 2) Подписи широко используются компилятором, например. предоставить определение идентификатора и в случае C++ выбрать наилучшую перегрузку. - person dirkgently; 24.02.2010

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

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

person Mark Ransom    schedule 24.02.2010
comment
Означает ли класс хранилища класс, к которому принадлежит функция? Какой смысл иметь понятие сигнатуры функции? Спасибо! - person Tim; 24.02.2010
comment
@Tim: Нет. Они относятся к применимой связи. - person dirkgently; 24.02.2010
comment
Я бы не стал слишком доверять статье из Википедии прямо сейчас. Это не очень хорошо написано. Статья Подпись метода немного лучше. - person Rob Kennedy; 24.02.2010
comment
Я подозреваю, что путаю свою терминологию - класс хранилища относится к переменным, а не к функциям. Я имел в виду характеристики, подразумеваемые, например, ключевыми словами static или extern. Я обновил свой ответ. - person Mark Ransom; 24.02.2010
comment
@Mark Ransom: static и extern — это классы хранения, которые могут применяться к функциям как в C, так и в C++. - person dirkgently; 24.02.2010
comment
В C++ возвращаемый тип не является частью сигнатуры функции, независимо от того, что говорит Википедия, хотя возвращаемый тип может быть частью сигнатуры функции для других языков (честно говоря, я не знаю). - person Michael Burr; 24.02.2010

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

e.g.

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

имеет ту же подпись, что и

void f(int, const char*);
person Ben Voigt    schedule 08.03.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++, чего ожидать, и если подпись не совпадает с прототипом, компилятор выдаст ошибку в контексте «ошибка объявления функции» или «несоответствие прототипа».

person t0mm13b    schedule 24.02.2010
comment
Спасибо! Итак, сигнатура функции — это часть определения функции, которая соответствует объявлению функции? - person Tim; 24.02.2010
comment
@ Тим: Да. Точно. :) Надеюсь, это имеет смысл для вас? - person t0mm13b; 24.02.2010
comment
В C объявление функции может не быть прототипом: int f(); является примером. - person Alok Singhal; 24.02.2010