Декларация или определение - PullRequest
2 голосов
/ 03 октября 2010

У меня путаница с декларацией и определением.

В заявлении

int switchon(float duration);

Q1. Определяется ли параметр 'duration' или он объявлен?

Согласно разделу 3.1 / 2 Священного Стандарта, это определение, но я не могу понять, почему.

Q2. В чем точная разница между декларацией и определением?

C ++ В двух словах говорит, что

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

Это определение «определения и объявления» также не помогает мне понять, почему «продолжительность» является определением, а не объявлением в приведенном выше утверждении.

REDIT:

Пост UncleO дал мне идею, и вот что я попробовал:

Я изменил свой код как:

int switchon(float duration, int duration);   // idea is to see what error 
                                              // compiler gives

int main()  {  }

ошибка C2371: «продолжительность»: переопределение; различные основные типы

Ответы [ 6 ]

1 голос
/ 04 октября 2010

Существует различие в определении термина определение между C и C ++. Эта разница не очень хорошо известна (я узнал об этом только при исследовании этого вопроса), и большинство людей и книг используют определение C также в контексте C ++.

В Си объявление также является определением, если оно имеет <выбрать из набора> дополнительных свойств.
В C ++ объявление является всегда определением, если оно не является одним из <выбирать из набора>.> Br /> Для большинства практических целей это различие между определениями определение не имеет никакого значения, пока вы не начнете рассматривать угловые случаи.

В Си структура-член и параметр в прототипе функции являются , а не определениями, поскольку они не обладают обязательным свойством резервирования памяти для объявленного объекта.
В C ++ переменная-член struct (или class) и параметр в прототипе являются определениями , поскольку они не попадают в список исключений.

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

Q1. Определяется ли параметр 'duration' или он объявлен?

Согласно буквальному прочтению стандарта C ++, он определяется. Но я надеюсь, что это является дефектом в стандарте, потому что объявленный имеет больше смысла для меня.

int switchon(float duration, int duration);   // idea is to see what error 
                                              // compiler gives

int main()  {  }
error C2371: 'duration' : redefinition; different basic types

Скорее всего, вы получите ту же ошибку для:

extern float duration;
extern int duration;

Это оба объявления, но диагностика компилятора может не отражать это.

1 голос
/ 03 октября 2010

Ответ на вопрос 1:

Идентификатор "duration" не определен и не объявлен. «switchon» - это идентификатор, объявленный в этом операторе как функция с параметром float, возвращающим int.

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

EDIT:

Какая неприятная перемена!

int switchon(float duration, int duration); // idea is to see what error compiler gives

int main() { }

error C2371: 'duration' : redefinition; different basic types 

Это определенный компилятор, который выдает эту ошибку, поэтому не обязательно является окончательным. Этот пример приводит к плохому коду, но, по моему мнению, он не должен выдавать эту конкретную ошибку.

С другой стороны,

int switchon(float duration, int duration){ return 0; }

int main() { }

должно привести к ошибке переопределения, указанной выше. В этом случае определяется switchon, что означает, что длительность float и int duration определяются как параметры в одной и той же области видимости с одинаковым именем.

Может случиться так, что компилятор чрезмерно усердствует или использует один и тот же механизм для анализа функции в обоих случаях. Это определенно ошибка во втором случае и просто плохая идея в первом случае, так что не плохо, что она выдает ошибку в обоих случаях.

Ответ на вопрос 2: Разница в том, что сказано в разделе, также объясненном в этом дубликате

0 голосов
/ 03 октября 2010
int switchon(float duration);

является прототипом функции / декларацией и просто уточняет порядок & типа аргументов, передаваемых функции, а также тип возвращаемого значения.

Это необходимо только в тех случаях, когда полное определение функции (т. Е. Что программа делает при вызове функции) помещается после вызова switchon() в какой-либо другой функции, наиболее вероятно, main().

В этом отношении все имена переменных, используемые в прототипе функции, являются просто заполнителями и могут быть безопасно опущены. Таким образом, ваше заявление можно было бы прочитать так:

int switchon(float);

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

Для этой цели некоторые учебники будут ссылаться на duration в вашем первом прототипе как фиктивная переменная .

0 голосов
/ 03 октября 2010

Q1: Это объявление, потому что фактическая реализация не была предоставлена ​​для функции "switchon".Если бы это было что-то вроде:

int switchon(float duration) { // do sth with duration return result; }

Тогда это было бы определением (b / c все детали предоставлены)

Q2: Объявление дает только сигнатуру, тогда как определение определяет, что на самом деле делает функция.

0 голосов
/ 03 октября 2010

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

Например, скажите, какое значение / содержание длительности основано только на этом примере?Ты не можешьСледовательно, это декларация.

0 голосов
/ 03 октября 2010

Линия:

int switchon(float duration);

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

A1: объявляется тот факт, что у вас есть параметр.

A2: В объявлении указывается сигнатура функции, а в определении указывается реализация и имена формальных параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...