Прямая ссылка против прямой декларации
Я немного смущен. В чем разница между предварительной декларацией и прямой ссылкой? В моей голове прямое объявление, когда вы объявляете функцию, которая еще не реализована, но это неправильно? Нужно ли вам смотреть на указанную ситуацию, чтобы объявить случай "прямой ссылкой" или "предварительным объявлением"?
3 ответа
Из Википедии:
Форвардная декларация
Объявление переменной или функции, которые еще не определены. Их определение можно увидеть позже.
Прямая ссылка
Аналогично предварительному объявлению, но там, где переменная или функция появляется первой, определение также на месте.
Форвардное объявление - это объявление метода или переменной перед ее реализацией и использованием. Цель предварительных объявлений - сэкономить время компиляции.
Прямое объявление переменной приводит к тому, что пространство памяти будет отложено, поэтому вы сможете позже установить значение этой переменной.
Предварительное объявление функции также называется "прототипом функции" и является оператором объявления, который сообщает компилятору, что является типом возвращаемой функции, каково имя функции и типы ее параметров. Компиляторы на языках, таких как C/C++ и Pascal, хранят объявленные символы (которые включают функции) в таблице поиска и ссылаются на них так, как они встречаются в вашем коде. Эти компиляторы читают ваш код последовательно, то есть сверху вниз, поэтому, если вы не пересылаете объявление, компилятор обнаруживает символ, на который он не может ссылаться в таблице поиска, и выдает ошибку, которую он не знает. как реагировать на функцию.
Форвардное объявление является подсказкой компилятору, который вы определили (заполнили реализацию) функции в другом месте.
Например:
int first(int x); // forward declaration of first
...
int first(int x) {
if (x == 0) return 1;
else return 2;
}
Но вы спрашиваете, почему бы нам просто не сделать так, чтобы компилятор делал два прохода для каждого исходного файла: первый для индексации всех символов внутри, а второй для анализа ссылок и их поиска? По словам Дана Стори:
Когда C был создан в 1972 году, вычислительные ресурсы были гораздо более скудными и требовали больших затрат - память, необходимая для хранения всей символической таблицы сложной программы, просто не была доступна в большинстве систем. Фиксированное хранилище также было дорогим и чрезвычайно медленным, поэтому такие идеи, как виртуальная память или хранение частей символической таблицы на диске, просто не позволили бы компилировать в разумные сроки... Когда вы имеете дело с магнитной лентой, где время поиска было измеряется в секундах и пропускная способность чтения измеряется в байтах в секунду (не в килобайтах или мегабайтах), что было довольно значимым.
C++, хотя и был создан почти 17 лет спустя, был определен как расширенный набор C, и поэтому должен был использовать тот же механизм.
Ко времени появления Java в 1995 году у средних компьютеров было достаточно памяти, чтобы держать символическую таблицу, даже для сложного проекта, уже не было существенным бременем. А Java не была разработана для обратной совместимости с C, поэтому ей не нужно было использовать устаревший механизм. C# был так же свободен.
В результате их разработчики решили перенести бремя разделения символьного объявления обратно на программиста и снова поместить его на компьютер, поскольку его стоимость пропорционально общим усилиям по компиляции была минимальной.
В Java и C# идентификаторы автоматически распознаются из исходных файлов и считываются непосредственно из символов динамической библиотеки. В этих языках заголовочные файлы не нужны по той же причине.
Прямая ссылка противоположна. Это относится к использованию объекта до его объявления. Например:
int first(int x) {
if (x == 0) return 1;
return second(x-1); // forward reference to second
}
int second(int x) {
if (x == 0) return 0;
return first(x-1);
}
Обратите внимание, что "прямая ссылка" иногда используется, хотя и реже, как синоним "прямого объявления".
Предварительные объявления используются для однопроходной компиляции языка (C, Pascal).
если прямые ссылки разрешены без предварительного объявления (Java, C#), требуется двухпроходный компилятор.