Найти в Дзене

Основы С++: Предварительное объявление функций и изменение порядка их определения

Оглавление

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

Когда вы напишите эту программу у себя. Вероятно, ваш редактор кода так же как и мой, не подчеркнет ошибку ни в одной из строк. Однако, стоит вам попробовать скомпилировать программу, как вы получите следующее:

-2

Когда компилятор достиг строки 4. Он просто не смог найти идентификатор (функции) diffrerence. Да, скажете вы, странно, ведь ниже в строке 6 мы определили его? Но все дело в том, что компилируется программа построчно. И на момент чтения строки 4, компилятор еще не видел строку 6.

Что же делать, чтобы исправить эту досадную ошибку?

Для начала, мы можем просто изменить порядок определения функций.

-3

Вот! Теперь наша программа компилируется без ошибок и выдаст нам тот результат, который мы хотим.

-4

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

Что можно сделать для того, чтобы функция difference была определена после функции main и при этом программа спокойно компилировалась и работала?

Можно (нужно) использовать предварительное объявление идентификатора.

Предварительное объявление

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

Прототип (функции) — это инструкция без тела функции, состоящая из типа, имени и параметров и заканчивающаяся точкой с запятой.

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

-5

На строке два мы использовали инструкцию предварительного определения функции difference. Теперь наш компилятор будет заранее знать, что функция difference существует. Он не будет выдавать ошибку в строке 4 и программа успешно запустится.

Другие типы предварительных объявлений, которые используются другими идентификаторами, мы рассмотрим в отдельных материалах.

Есть ли разница между объявлением и определением?

Определение — это набор инструкций, который реализует функцию или создает экземпляр переменной (идентификатора).

-6

Определение нужно для того, чтобы компоновщик (линкер) не выводил ошибку. Если в программе будет присутствовать идентификатор без определения, то наша программа не будет собрана.

Для инструкций определения есть известное в С++ правило: ODR — one defenition rule — правило одного определения.

ODR сформировано из трех постулатов:

1. В заданном файле функция, объект или шаблон могут иметь только одно определение.

2. В заданной программе (в программе может быть много файлов) объект или обычная функция могут иметь только одно определение.

3. Для типов, шаблонов и встроенных функций (пока мы не рассматривали эти штуки) допускается иметь более одного идентичного определения в разных файлах одной программы.

И напоследок, правило: Все определения являются объявлениями не всегда работает в обратную сторону.

Объявления, которые не являются определениями, называются чистыми и правило ODR к ним не применяется. Вы можете сделать множество чистых объявлений для идентификатора (например, предварительно объявить об одной функции несколько раз), хотя это и считается "избыточным".

Рубрика "Вопросы комментаторов":

— А зачем нужно предварительное объявление?

— Об этом я расскажу совсем скоро в следующей статье. И не только расскажу, но и покажу, где оно будет необходимо. Наберитесь терпения, если вы читаете этот текст, а статья еще не вышла.

На этом сегодня все. Спасибо за внимание.

Подписывайтесь на канал, чтобы не пропустить выход новых материалов.

Оставляйте лайки и комментарии.