Страницы

Поиск по вопросам

среда, 22 мая 2019 г.

Объявление и определение функции (порядок размещения)

В каждой единице трансляции, объявление функции обязано предшествовать её вызову. Если это условие выполняется, то порядок размещения определения уже не имеет особого значения.
Какой вариант предпочтительней и почему? (сначала функция объявлена, а затем определена или наоборот)
void someFunction(); // declaration void someFunction() { cout << "hello" << endl; }
int main() { someFunction(); // function call return 0; }
или
void someFunction() { cout << "hello" << endl; } void someFunction(); // declaration
int main() { someFunction(); // function call return 0; }


Ответ

Какой вариант предпочтительней и почему? (сначала функция объявлена, а затем определена или наоборот)

Хотелось бы узнать причину именно такого порядка размещения. Что это? удобство восприятия программы, отдельное положение стандарта языка, код в этом случае быстрее компилируется или есть ещё какая-то причина?
Причина та же самая, по которой вообще в язык добавлена возможность объявлять функции без их определения.
Представьте что возможности объявить (без определения!) функции нет. И вам надо написать две функции, вызывающие друг друга:
void SomeFirstFunction(int n) { cout << n << endl; SomeSecondFunction(n); }
void SomeSecondFunction(int n) { if (n > 0) { SomeFirstFunction(n - 1); } }
int main() { SomeFirstFunction(5); }
Компилятор разбирает файл сверху вниз. Он доходит до строки
SomeSecondFunction(n);
В этот момент он понятия не имеет, что это за SomeSecondFunction и какие параметры она принимает - она ведь еще не определена. И он падает с ошибкой:
In function 'void SomeFirstFunction(int)': error: 'SomeSecondFunction' was not declared in this scope
Перестановка местами SomeSecondFunction и SomeFirstFunction, очевидно, не поможет.
Поэтому в язык добавлен хак - вы можете сказать компилятору "SomeSecondFunction - это функция вот с такими параметрами, и она будет определена где-то ниже. Или даже не ниже, а вообще в другом файле - вобщем, смело считай это функцией, генерируй код для ее вызова, потом линковщик разберется где эта функция на самом деле лежит".
// предупредили компилятор void SomeSecondFunction(int n);
void SomeFirstFunction(int n) { cout << n << endl; // компилятор спокойно сгенерировал вызов еще не определенной (но объявленной!) функции SomeSecondFunction(n); }
void SomeSecondFunction(int n) { if (n > 0) { SomeFirstFunction(n - 1); } }
При этом нет никакого смысла в объявлении SomeFirstFunction после ее определения - компилятор и так знает что это за функция, ему от еще одного объявления уже известного факта лучше не станет.

А вот в примерах из вашего вопроса объявление полностью избыточно. Т.е. ни один из этих вариантов не предпочтительней - они оба бессмысленны, т.к. эквивалентны варианту вообще без declaration:
void someFunction() { cout << "hello" << endl; }
int main() { someFunction(); // function call return 0; }

Комментариев нет:

Отправить комментарий